我爱嵌入式系统

当前位置:首页 > 软件天地 > 业内资讯 > 详细内容
驱动器主机机485通讯
发布时间:2009-11-13  阅读次数:383  字体大小: 【】 【】【

/*----------------------------------------------------------------------
功能描述:驱动器主机机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);
}

我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

51RTOS.com 版权所有  

Copyright 20006-2009 我爱嵌入式 ( 51RTOS.com ) All rights reserved 沪ICP备09080633号