找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2726|回复: 9
收起左侧

风向传感器连接单片机,用LCD显示数据,求大家帮忙看看程序哪里有问题

[复制链接]
ID:796670 发表于 2020-12-8 21:51 | 显示全部楼层 |阅读模式
本帖最后由 明日香 于 2020-12-9 13:30 编辑

风向传感器与单片机连接,用LCD1602显示风向数据,传感器返回的的应答帧数据是9个,其中LCD显示第7个数据
求大家帮忙看看哪里有问题:

这是单片机原理图: tu.PNG

这是传感器说明书:
风向传感器1.PNG 风向传感器3.PNG 风向传感器5.PNG
以下为源程序:
  1. #include <stc12c5a.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. #include <intrins.h>
  7. #define uchar unsigned char
  8. #define uint  unsigned int
  9.         
  10. sbit E=P2^2;    //1602使能引脚
  11. sbit RW=P2^1;    //1602读写引脚   
  12. sbit RS=P2^0;    //1602数据/命令选择引脚

  13. uchar table[24]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  14. uchar wind_direction[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xC4,0x0B};//风向传感器问询帧
  15. uchar wind_direction1;//单片机接收风向数据
  16. uchar strwind[3];
  17. uchar num=0;

  18. void delay(uint z)//延时函数
  19. {
  20.         uint x,y;
  21.         for(x=z;x>0;x--);
  22.                 for(y=110;y>0;y--);
  23. }

  24. void wcmd(uchar del)//写命令函数
  25. {
  26.   RS=0;//命令选择端
  27.         delay(10);
  28.         RW=0;//写命令
  29.         delay(10);
  30.         P0=del;  //把命令字写入
  31.         delay(10);
  32.         E=1;//使能
  33.         delay(10);
  34.         E=0;
  35. }

  36. void lcd1602_writedata(uchar dat)//写数据函数
  37. {
  38.   delay(10);
  39.         RS=1;//数据选择端
  40.         delay(10);
  41.         RW=0;//写命令
  42.         delay(10);
  43.         P0=dat;  //把要显示的数据写入
  44.         delay(10);
  45.         E=1;
  46.         delay(10);
  47.         E=0;
  48. }

  49. void lcd1602_init()//LCD初始化
  50. {
  51. wcmd(0x38);
  52. wcmd(0x0C);
  53. wcmd(0x06);
  54. wcmd(0x01);
  55. }

  56. void init()  //系统初始化
  57. {
  58. TMOD |=0X20;//定时器T1,方式2,波特率由PCON寄存器的SMOD决定
  59. SCON=0x50; //REN RI TI,RI为0,TI为0
  60. //串行口1方式1 SCON是串行口1的串行控制寄存器,REN为1,允许接收
  61. PCON=0x00;//各工作方式波特率加倍
  62. TH1=0xfD;//9600bps@11.0592
  63. TL1=0xfD;
  64. TR1=1; //定时器1中断打开
  65. EA=1;//cpu总中断允许位,1为开放中断
  66. ES=1;// 1允许串行口中断
  67. }

  68. void main()
  69. {
  70.         uchar m=0;
  71.         init();
  72.   while(1)
  73.         {
  74.          int i;               
  75.          for(i=0;i<8;i++)
  76.                 {
  77.                 SBUF=wind_direction[i];//风向数据
  78.                         while(TI==0);
  79.       {
  80.                                          }                        //数据发送结束时TI自动置1
  81.                         TI=0;
  82.                         
  83.                 }
  84.                 delay(1000);
  85.                 strwind[0]=(wind_direction1/100%10)+'0';
  86.                 strwind[1]=(wind_direction1/10%10)+'0';
  87.                 strwind[2]=(wind_direction1%10)+'0';
  88.                 lcd1602_init();
  89.                 delay(1000);
  90.                 wcmd(0x80);
  91.                 delay(1000);
  92.                 for(m=0;m<2;m++)
  93.                 {
  94.                 lcd1602_writedata(strwind[m]);
  95.                 }
  96.                 delay(5000);
  97.   }
  98. }

  99. void UART_1() interrupt 4
  100. {
  101.         //接收完缓冲数据后RI置1
  102.         if(RI)//如果RI为1,即如果收到
  103.         {
  104.                 RI=0; //RI置0
  105.                 if(num==0)
  106.                 {
  107.                         if(SBUF==0x01)
  108.                         {
  109.                                 table[num++] = SBUF;
  110.                         }
  111.                 }
  112.                 else
  113.                 {
  114.                         table[num++]=SBUF;//风向数据
  115.                         if(num>8)
  116.                         {
  117.                                 num=0;
  118.                                 wind_direction1=table[6];//风向数据给wind_direction1[0]
  119.                         }
  120.                 }
  121.         }
  122. }
复制代码

最终运行后LCD只显示00,请问程序哪里错了?是不是初始化或者中断部分有问题?求大家帮忙解答,谢谢。

风向传感器5.PNG
回复

使用道具 举报

ID:592807 发表于 2020-12-9 08:38 | 显示全部楼层
哎,你上电路图和风向传感器的说明书吧,你这个设备地址码可能是I2C的通讯地址。如果是I2C的话你可能从一开始就错了。
回复

使用道具 举报

ID:796670 发表于 2020-12-9 13:31 | 显示全部楼层
黄youhui 发表于 2020-12-9 08:38
哎,你上电路图和风向传感器的说明书吧,你这个设备地址码可能是I2C的通讯地址。如果是I2C的话你可能从一开 ...

你好,已经上传电路图和说明书,请您再帮忙看一下吧,感谢不已~
回复

使用道具 举报

ID:824490 发表于 2020-12-9 16:37 | 显示全部楼层
风向传感器是哪个器件?
回复

使用道具 举报

ID:592807 发表于 2020-12-9 18:55 | 显示全部楼层
这个00可能时你数组里面本来就存在的数据,你根本就没收到数据,试一下吧接收到的所有帧都打印出来
51hei截图20201209185354.png
回复

使用道具 举报

ID:213173 发表于 2020-12-9 19:14 | 显示全部楼层
你搞了这么长时间还搞不定,给你改写了,用串口助手模拟传感器实物验证没有问题。根据其基本框架,你自己补充完善。
无标题.jpg


  1. #include <STC12C5A60S2.H>
  2. #define uchar unsigned char
  3. #define uint  unsigned int
  4.         
  5. sbit E=P2^2;    //1602使能引脚
  6. sbit RW=P2^1;    //1602读写引脚   
  7. sbit RS=P2^0;    //1602数据/命令选择引脚

  8. uchar table1[]="Wind Direction ";
  9. uchar table2[]="The Angle:     ";
  10. uchar wind_direction[8]={0x01,0x03,0x00,0x00,0x00,0x02,0xC4,0x0B};//风向传感器问询帧
  11. uchar rec_buf[9];
  12. uchar strwind[]={'0','0','0',0xdf,' '};
  13. uchar error[]="Error";
  14. uint  wind_direction1;//单片机接收风向数据
  15. uint  temp;
  16. uchar num=0;
  17. bit   flag=0;
  18. bit   sign=1;
  19. uint  Angle;
  20. void delay(uint z)//延时函数
  21. {
  22.         uint x,y;
  23.         for(x=z;x>0;x--);
  24.                 for(y=110;y>0;y--);
  25. }

  26. void wcmd(uchar del)//写命令函数
  27. {
  28.         RS=0;//命令选择端
  29.         RW=0;//写命令
  30.         P0=del;  //把命令字写入
  31.         delay(1);
  32.         E=1;//使能
  33.         delay(1);
  34.         E=0;
  35. }

  36. void lcd1602_writedata(uchar dat)//写数据函数
  37. {
  38.         RS=1;//数据选择端
  39.         RW=0;//写命令
  40.         P0=dat;  //把要显示的数据写入
  41.         delay(1);
  42.         E=1;
  43.         delay(1);
  44.         E=0;
  45. }

  46. void lcd1602_init()//LCD初始化
  47. {
  48.         wcmd(0x38);
  49.         wcmd(0x0C);
  50.         wcmd(0x06);
  51.         wcmd(0x01);
  52. }

  53. void init()  //系统初始化
  54. {
  55.         TMOD |=0X20;//定时器T1,方式2,波特率由PCON寄存器的SMOD决定
  56.         SCON=0x50; //REN RI TI,RI为0,TI为0
  57.         //串行口1方式1 SCON是串行口1的串行控制寄存器,REN为1,允许接收
  58.         PCON=0x00;//各工作方式波特率加倍
  59.         TH1=0xfD;//9600bps@11.0592
  60.         TL1=0xfD;
  61.         TR1=1; //定时器1中断打开
  62.         EA=1;//cpu总中断允许位,1为开放中断
  63.         ES=1;// 1允许串行口中断
  64. }

  65. void main()
  66. {
  67.         uchar i;
  68.         init();
  69.         lcd1602_init();
  70.         wcmd(0x81);//第一行
  71.         for(i=0;i<14;i++)
  72.                 lcd1602_writedata(table1[i]);
  73.         wcmd(0xc1);//第二行
  74.         for(i=0;i<15;i++)
  75.                 lcd1602_writedata(table2[i]);
  76.         while(1)
  77.         {
  78.                 EA=0;//关中断
  79.                 for(i=0;i<8;i++)//问询
  80.                 {
  81.                         SBUF=wind_direction[i];//风向数据
  82.                         while(!TI);//数据发送结束时TI自动置1
  83.                         TI=0;
  84.                 }
  85.                 EA=1;//开中断
  86.                 delay(1000);//等待1秒
  87.                 if(flag==1)
  88.                 {
  89.                         flag=0;
  90.                         temp=rec_buf[8]<<8|rec_buf[7];//提取验证码
  91.                         if(temp==0xc8db)//验证正确
  92.                         {
  93.                                 sign=1;
  94.                                 wind_direction1=rec_buf[5]<<8|rec_buf[6];
  95.                                 strwind[0]=(wind_direction1/100%10)+'0';
  96.                                 strwind[1]=(wind_direction1/10%10)+'0';
  97.                                 strwind[2]=(wind_direction1%10)+'0';
  98.                         }
  99.                         else//错误,清除缓存
  100.                         {
  101.                                 sign=0;
  102.                                 for(i=0;i<9;i++)
  103.                                         rec_buf[i]=0;
  104.                         }
  105.                 }
  106.                 wcmd(0xc0+11);//字符显示起始位置
  107.                 if(sign)
  108.                 {
  109.                         for(i=0;i<5;i++)
  110.                                 lcd1602_writedata(strwind[i]);//显示风向角度数据
  111.                 }
  112.                 else
  113.                 {
  114.                         for(i=0;i<5;i++)
  115.                                 lcd1602_writedata(error[i]);//显示错误字符
  116.                 }
  117.         }
  118. }

  119. void UART_1() interrupt 4
  120. {
  121.         RI=0; //RI置0
  122.         rec_buf[num] = SBUF;
  123.         if(rec_buf[0]==0x01)//验证数据头,正确继续接收,错误被后续数据覆盖
  124.         {
  125.                 num++;
  126.                 if(num>=9)                        //帧长度
  127.                 {
  128.                         flag=1;                        //帧接收完成标志置1
  129.                         num=0;                        //计数变量清0
  130.                 }
  131.         }
  132. }
  133. //01 03 04 00 02 00 5a db c8
复制代码





回复

使用道具 举报

ID:213173 发表于 2020-12-9 20:23 | 显示全部楼层
楼主注意,上面示例的校验码处理方式只是简单模拟解析数据,不是真正按CRC算法处理校验码。实际应用中参考制造商资料。
回复

使用道具 举报

ID:796670 发表于 2020-12-10 10:31 | 显示全部楼层
wulin 发表于 2020-12-9 19:14
你搞了这么长时间还搞不定,给你改写了,用串口助手模拟传感器实物验证没有问题。根据其基本框架,你自己补 ...

谢谢,非常感谢
回复

使用道具 举报

ID:796670 发表于 2020-12-10 10:37 | 显示全部楼层
wulin 发表于 2020-12-9 20:23
楼主注意,上面示例的校验码处理方式只是简单模拟解析数据,不是真正按CRC算法处理校验码。实际应用中参考 ...

您好,请问您是用什么软件模拟传感器的呢?是类似于stc-icp串口助手吗?
回复

使用道具 举报

ID:213173 发表于 2020-12-10 11:25 | 显示全部楼层
明日香 发表于 2020-12-10 10:37
您好,请问您是用什么软件模拟传感器的呢?是类似于stc-icp串口助手吗?

就是stc-icp串口助手
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表