51RTOS.com 版权所有 Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号 |
我爱嵌入式系统
/*----------------------------------------------------------------------
功能描述:驱动器主机机485通讯 -通讯速率4800bps-用于测试485总线
本程序realease版本在avr开发板“05-4-28 by hank”上面运行
PC5 = 1--发送允许控制脚
--------------------------------- --------------------------------------
------------------------------------------------------------------------ */
/*------------------------------------------------------------------------
一共6个字节
第一个字节始终为0xAA,它作为帧头以用来标识一个数据帧的起始;
第二个字节为地址字节,用来标识这个数据包的目的CPU(当数据包是
主控制CPU 发出时)或者是源CPU(当数据包是从控制CPU发出时);
第三个字节为命令字节;
第四个字节为校验字节,其作为整个帧的校验(累加和校验);
第五和第六字节为数据字节,其为这一个数据包中与命令有关的有效数据。
------------------------------------------------------------------------*/
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <inttypes.h>
//#include "LCD.h"
#define COM_ADD 01//从机地址
#define UART_CTRL_PORT PORTA
#define UART_CTRL_DDR DDRA
#define UART_CTRL_NUM PA7
#define tx485en() UART_CTRL_PORT |= (1<<UART_CTRL_NUM) //发送
#define rx485en() UART_CTRL_PORT &= ~(1<<UART_CTRL_NUM) //接收
uint8_t char_txbuf[6]; //串行通信的缓冲区
uint8_t char_rxbuf[6];
uint8_t TX_js, RX_js; //字节个数计数
uint8_t RX_bz, TX_bz; //帧接受完毕标志
SIGNAL(SIG_UART_RECV)
{
for(RX_js = 0; RX_js<5; RX_js++)
char_rxbuf[RX_js] = char_rxbuf[RX_js+1];
char_rxbuf[5] = UDR;
//接收的字节首先存到数组末尾,5次循环后帧头0xAA就处于首位
if((char_rxbuf[0] == 0xaa)&&(char_rxbuf[1] == COM_ADD)
&&((uint8_t)((char_rxbuf[2]+char_rxbuf[4]+char_rxbuf[5]))
==char_rxbuf[3])) //检查校验码)
RX_bz = 1;
//帧接受完毕标志,
}
SIGNAL(SIG_UART_TRANS)
{
if(TX_js<6)
{
UDR = char_txbuf[TX_js];
TX_js++;
}
else {
TX_bz = 0;//串口发送忙标志清零
rx485en();
}
}
//启动发送,并传出第一个数据
void UART_Putchar(void)
{
TX_bz = 1; //串口发送忙标志
tx485en();
UDR = char_txbuf[0];
TX_js = 1;
}
//不使能电机
void motor_no(void)
{
char_txbuf[0] = 0xaa;
char_txbuf[1] = COM_ADD;
char_txbuf[2] = 0;
char_txbuf[4] = 0;
char_txbuf[5] = 0;
char_txbuf[3] = (uint8_t) (char_txbuf[2] + char_txbuf[4] + char_txbuf[5]);
UART_Putchar();
while(TX_bz != 0);
}
//使能电机
void motor_yes(void)
{
char_txbuf[0] = 0xaa;
char_txbuf[1] = COM_ADD;
char_txbuf[2] = 1;
char_txbuf[4] = 0;
char_txbuf[5] = 0;
char_txbuf[3] = (uint8_t) (char_txbuf[2] + char_txbuf[4] + char_txbuf[5]);
UART_Putchar();
while(TX_bz != 0);
}
/*---------------------------------------------------
设置步进电机的增量转角和方向
n增量步数,0~180°对应n=0~96*20(1920),这儿n是8位字节,
但每次增量步数不要超过255,便于传输,也防止转向过急
d=0反转 d=1正转 设定电机转动方向
---------------------------------------------------*/
void stepper_ctrl(uint8_t n, uint8_t d)
{
char_txbuf[0] = 0xaa;
char_txbuf[1] = COM_ADD;
char_txbuf[2] = 2;
char_txbuf[4] = n;
char_txbuf[5] = d;
char_txbuf[3] = (uint8_t) (char_txbuf[2] + char_txbuf[4] + char_txbuf[5]);
UART_Putchar();
while(TX_bz != 0);
}
/*---------------------------------------------------
设置直流电机的速度和方向
n 速度等级0~30,PID的运算周期1s
d=0反转 d=1正转 设定电机转动方向
---------------------------------------------------*/
void dcmotor_ctrl(uint8_t n, uint8_t d)
{
char_txbuf[0] = 0xaa;
char_txbuf[1] = COM_ADD;
char_txbuf[2] = 3;
char_txbuf[4] = n;
char_txbuf[5] = d;
char_txbuf[3] = (uint8_t) (char_txbuf[2] + char_txbuf[4] + char_txbuf[5]);
UART_Putchar();
while(TX_bz != 0);
}
/*---------------------------------------------------
查询步进电机的目前绝对转角记录steps=0~1920(假设不丢步)
复位值steps 为1920/2
---------------------------------------------------*/
uint16_t angle_inquire(void)
{
char_txbuf[0] = 0xaa;
char_txbuf[1] = COM_ADD;
char_txbuf[2] = 4;
char_txbuf[4] = 0;
char_txbuf[5] = 0;
char_txbuf[3] = (uint8_t) (char_txbuf[2] + char_txbuf[4] + char_txbuf[5]);
UART_Putchar();
while(TX_bz != 0);
while(RX_bz == 0);
return( (((uint16_t)char_rxbuf[4]) << 8) + (uint16_t)char_rxbuf[5] );
}
/*---------------------------------------------------
5. case 5: 查询直流电机速度参数Vsam=0~30
---------------------------------------------------*/
uint8_t vel_inquire(void)
{
char_txbuf[0] = 0xaa;
char_txbuf[1] = COM_ADD;
char_txbuf[2] = 5;
char_txbuf[4] = 0;
char_txbuf[5] = 0;
char_txbuf[3] = (uint8_t) (char_txbuf[2] + char_txbuf[4] + char_txbuf[5]);
UART_Putchar();
while(TX_bz != 0);
while(RX_bz == 0);
return(char_rxbuf[4]);
}
static void avr_init(void)
{
// Initialize device here.
//485初始化接收状态
UART_CTRL_DDR |= 1<<UART_CTRL_NUM;
rx485en();
RX_bz = 0;
TX_bz = 0;
//uart初始化
//4800bps,8个数据位,1个停止位,无奇偶校验,异步正常模式
//接收使能、发送使能、接收中断允许、发送中断允许
//UCSRA和UCSRC采用默认值
UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN);
UBRRL=51; // baud=4800 UBRR=CK/(baud*16) -1
return;
}
int main(void)
{
unsigned int i;
avr_init();
sei();
//PC7-LED, PC6-KEY,使能上拉电阻
DDRC = (1<<DDC7) | (0<<DDC6);
PORTC = (0<<PC7) | (1<<PC6);
/*------------------------------------------------
//测试步进电机专用
while(1)
{
while(bit_is_set(PINC, PC6));
motor_yes();
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
stepper_ctrl(250, 1);
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
stepper_ctrl(250, 1);
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
stepper_ctrl(250, 1);
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
stepper_ctrl(250, 1);
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
motor_no();
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
}
------------------------------------------------*/
// 测试各个功能,5种命令,2005-7-18
while(1)
{
while(bit_is_set(PINC, PC6));
motor_yes();
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
stepper_ctrl(250, 1);
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
dcmotor_ctrl(10, 1);
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
angle_inquire();
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
vel_inquire();
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
motor_no();
for(i=6000; i>0; i--);
while(bit_is_clear(PINC, PC6));
while(bit_is_set(PINC, PC6));
}
/*------------------------------------------------
给从机发命令测试程序,按键一次发命令一次,循环执行,led闪烁指示系统正常工作
2005.7.18调试通过
unsigned char addr=0;
while(1)
{
if(bit_is_clear(PINC, PC6))
{
char_txbuf[0] = 0xaa;
char_txbuf[1] = COM_ADD;
char_txbuf[2] = addr;
char_txbuf[4] = 6;
char_txbuf[5] = 0;
char_txbuf[3] = (uint8_t) (char_txbuf[2] + char_txbuf[4] + char_txbuf[5]);
UART_Putchar();
while(TX_bz != 0);
addr += 1;
if(addr > 5)
addr = 0;
while(bit_is_clear(PINC, PC6));
}
PORTC |= (1 << PC7);
for(i=6000; i>0; i--);
PORTC &= ~(1 << PC7);
for(i=6000; i>0; i--);
}
------------------------------------------------*/
return(0);
}
51RTOS.com 版权所有 Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号 |