编程知识 cdmana.com

单片机采集485型传感器数据

最近做一个项目,展很慢,希望大家可以帮忙指点指点。项目:由 CC2530板子对一个485型modbus传感器进行数据采集,代码如下,希望可以得到指点
#include <iocc2530.h>#include <string.h>#define uint unsigned int#define uchar unsigned char#define ulong unsigned long#define rs485_de P1_7#define rs485_re P1_5//延时啊void delay(unsigned int t,unsigned int u){        unsigned int i,j;        for(i=0;i<t;i++)        for(j=0;j<u;j++);}//延时void Delay(uint n){uint i;for(i = 0;i<n;i++);for(i = 0;i<n;i++);for(i = 0;i<n;i++);for(i = 0;i<n;i++);for(i = 0;i<n;i++);}void Init485_Port(){  //初始化RS485   P1SEL &= ~0xA0;            //P1-7作 P1-5为通用I/O口  P1DIR |= 0xA0;             }void Init485_send() //传感器发送数据 {  Init485_Port();  rs485_de =0;  rs485_re =0;}void Init485_rec() //传感器发接收数据 {  Init485_Port();  rs485_de =1;  rs485_re =1;}/* 485通信 */unsigned char len;unsigned char buf[40]={
   
   
   
   0x01,0x03,0x00,0x00,0x00,0x02,0xC4,0x0B};  //读取读取叶面温湿度设备(地址 0x01)的温湿度值int flagFrame = 0;  //帧接收完成标志,即接收到一帧新数据int flagTxd = 0; //单字节发送完成标志,用来替代 TXD 中断标志位unsigned char cntRxd = 0;   //接收字节计数器unsigned char  bufRxd[64];  //接收字节缓冲区unsigned char TORH=0;//定时器中用到unsigned char TORL=0;unsigned int wendu_H=0x00;                 //温度值高4位字节unsigned int wendu_L=0x00;                 //温度值低4位字节unsigned int shidu_H=0x00;                 //湿度值高4位字节unsigned int shidu_L=0x00;                 //湿度值低4位字节/* 串口配置函数,baud-通信波特率 */void initUART0(void){  CLKCONCMD &= ~0x40;                           //设置系统时钟源为32MHZ晶振  while(CLKCONSTA & 0x40);                      //等待晶振稳定  CLKCONCMD &= ~0x47;                           //设置系统主时钟频率为32MHZ    PERCFG = 0x00;                      //位置1 P0口  P0SEL = 0x3c;                  //P0用作串口  P2DIR &= ~0XC0;                               //P0优先作为UART0     U0CSR |= 0x80;                  //串口设置为UART方式  U0GCR |= 7;                  U0BAUD |= 59;                  //波特率设为4800//中断设置可能需要修改  UTX0IF = 1; //UART0 TX 中断标志初始置位 1  U0CSR |= 0X40; //允许接收  IEN0 |= 0x84; //开总中断,接收中断}/* 串口数据写入,即串口发送函数,buf-待发送数据的指针,len-指定的发送长度 */void UartWrite(unsigned char *buf, unsigned char len){        Init485_rec();    while (len--)  //循环发送所有字节    {        flagTxd = 0;       //清零发送标志        U0DBUF = *buf++;     //发送一个字节数据        while (!flagTxd); //等待该字节发送完成    }        Delay(500);        Init485_send();}/* 串口数据读取函数,buf-接收指针,len-指定的读取长度,返回值-实际读到的长度 */unsigned char UartRead(unsigned char *buf, unsigned char len){    unsigned char i;         if (len > cntRxd)  //指定读取长度大于实际接收到的数据长度时,   {                     //读取长度设置为实际接收到的数据长度       len = cntRxd;   }   for (i=0; i<len; i++)  //拷贝接收到的数据到接收指针上   {       *buf++ = bufRxd[i];   }   cntRxd = 0;  //接收计数器清零   return len;  //返回实际读取长度}/* 串口接收监控,由空闲时间判定帧结束,需在定时中断中调用,ms-定时间隔 */void UartRxMonitor(unsigned char ms){    static unsigned char cntbkp = 0;    static unsigned char idletmr = 0;    if (cntRxd > 0)  //接收计数器大于零时,监控总线空闲时间    {        if (cntbkp != cntRxd)  //接收计数器改变,即刚接收到数据时,清零空闲计时        {            cntbkp = cntRxd;            idletmr = 0;        }        else                      //接收计数器未改变,即总线空闲时,累积空闲时间        {            if (idletmr < 30) //空闲计时小于 30ms 时,持续累加            {                idletmr += ms;                if (idletmr >= 30) //空闲时间达到 30ms 时,即判定为一帧接收完毕                {                    flagFrame = 1;  //设置帧接收完成标志                }            }        }    }    else    {        cntbkp = 0;    }}/**************************************************************** 中断处理函数****************************************************************/#pragma vector = URX0_VECTOR__interrupt void UART0_ISR(void){ if (URX0IF)  //接收到新字节    {        URX0IF = 0;  //清零接收中断标志位        if (cntRxd < sizeof(bufRxd)) //接收缓冲区尚未用完时,        {                                          //保存接收字节,并递增计数器            bufRxd[cntRxd++] = U0DBUF;        }    }    if (UTX0IF)  //字节发送完毕    {        UTX0IF = 0;   //清零发送中断标志位        flagTxd = 1;  //设置字节发送完成标志    }   }/**************************************************************** 定时器****************************************************************/void ConfigTimer0(unsigned int ms){    unsigned long tmp;        tmp=16000000/12;          //12M晶振        tmp=(tmp*ms)/1000;        tmp=65536-tmp;        tmp=tmp+33;        T1CTL = 0x0d;        TORH=(unsigned char)(tmp>>8);        TORL=(unsigned char)tmp;        T1CC0L=TORL;        T1CC0H=TORL;        T1IE=1;        T1OVFIM=1;        EA=1;        T1CTL|=0x03;}void main(){ConfigTimer0(1);initUART0();         //设置波特率2400delay(200,500);UartWrite(buf,len);         //向传感器发送命令,01 03 02 00 00 03 04 73if (flagFrame) //有命令到达时,读取处理该命令    {       flagFrame = 0;       len = UartRead(buf, sizeof(buf));  //将接收到的命令读取到缓冲区中        }shidu_H=bufRxd[3];                //数据帧第3字节是温度值高位,shidu_L=bufRxd[4];                //数据帧第4字节是温度值低位。wendu_H=bufRxd[5];                //数据帧第4字节是温度值高位,wendu_L=bufRxd[6];                //数据帧第5字节是温度值低位。}/**************************************************************** 定时器中断****************************************************************/#pragma vector = T1_VECTOR__interrupt void T1_INT(void){        T1CC0L=TORL;        T1CC0H=TORH;        UartRxMonitor(1);  //串口接收监控}
运行后没有效果,前期进行过485通讯测试,硬件正常可正常收发
希望能得到代码上的指导,可以实现设备的温湿度采集

版权声明
本文为[CSDN问答]所创,转载请带上原文链接,感谢
https://ask.csdn.net/questions/7765366

Scroll to Top