找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1704|回复: 9
打印 上一主题 下一主题
收起左侧

如何让单片机在采集AD信号时(ADC是查询方式),通过中断串口控制单片机1.3和1.5管...

[复制链接]
跳转到指定楼层
楼主
ID:973635 发表于 2021-10-20 17:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如何让单片机在采集AD信号时(ADC是查询方式),通过中断串口控制单片机1.3和1.5管脚的灯的亮灭。单独测试ADC可以,加入中断就没反应了。代码如下如何让单片机在采集AD信号时(ADC是查询方式),通过中断串口控制单片机1.3和1.5管脚的灯的亮灭。单独测试ADC可以,加入中断就没反应了。代码如下
  1. #include <stc15w408as.h>
  2. #include <intrins.h>
  3. #define FOSC    11059200L
  4. #define BAUD    9600

  5. typedef unsigned char BYTE;
  6. typedef unsigned int WORD;

  7. #define     URMD    0           //0:使用定时器2作为波特率发生器
  8.                                 //1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器                                //2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器                        
  9. sfr ADC_LOW2    =   0xBE;           //ADC低2位结果

  10. #define ADC_POWER   0x80            //ADC电源控制位
  11. #define ADC_FLAG    0x10            //ADC完成标志
  12. #define ADC_START   0x08            //ADC起始控制位
  13. #define ADC_SPEEDLL 0x00            //540个时钟
  14. #define ADC_SPEEDL  0x20            //360个时钟
  15. #define ADC_SPEEDH  0x40            //180个时钟
  16. #define ADC_SPEEDHH 0x60            //90个时钟

  17. sbit addA = P1^3;
  18. sbit addB = P1^5;
  19. BYTE ch = 0;
  20. void InitUart();
  21. void InitADC();
  22. void SendData(BYTE dat);
  23. BYTE GetADCResult(BYTE ch);
  24. void Delay(WORD n);
  25. void ShowResult(BYTE ch);

  26. void main()
  27. {
  28.     InitUart();                     //初始化串口
  29.     InitADC();                      //初始化ADC
  30.     while (1)
  31.     {
  32.              ShowResult(0);              //显示通道0
  33.     }
  34. }

  35. /*----------------------------发送ADC结果到PC----------------------------*/
  36. void ShowResult(BYTE ch)
  37. {
  38. //    SendData(ch);                   //显示通道号
  39.     SendData(GetADCResult(ch));     //显示ADC高8位结果

  40. //    SendData(ADC_LOW2);           //显示低2位结果
  41. }

  42. /*----------------------------读取ADC结果----------------------------*/
  43. BYTE GetADCResult(BYTE ch)
  44. {
  45.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
  46.     _nop_();                        //等待4个NOP
  47.     _nop_();
  48.     _nop_();
  49.     _nop_();
  50.     while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成
  51.     ADC_CONTR &= ~ADC_FLAG;         //Close ADC

  52.     return ADC_RES;                 //返回ADC结果
  53. }

  54. /*----------------------------初始化串口----------------------------*/
  55. void InitUart()
  56. {
  57.     SCON = 0x5a;                //设置串口为8位可变波特率
  58.     T2L = (65536 - (FOSC/4/BAUD));
  59.     T2H = (65536 - (FOSC/4/BAUD)) >> 8;
  60.     AUXR = 0x14;                //T2为1T模式, 并启动定时器2
  61.     AUXR |= 0x01;               //选择定时器2为串口1的波特率发生器
  62.       EA = 1;
  63.       ES = 1;
  64. }

  65. /*----------------------------初始化ADC----------------------------*/
  66. void InitADC()
  67. {
  68.     P1ASF = 0xff;                   //设置P1口为AD口
  69.     ADC_RES = 0;                    //清除结果寄存器
  70.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
  71.     Delay(2);                       //ADC上电并延时
  72. }

  73. /*----------------------------发送串口数据----------------------------*/
  74. void SendData(BYTE dat)
  75. {
  76.     while (!TI);                    //等待前一个数据发送完成
  77.     TI = 0;                         //清除发送标志
  78.     SBUF = dat;                     //发送当前数据
  79. }

  80. /*----------------------------软件延时----------------------------*/
  81. void Delay(WORD n)
  82. {
  83.     WORD x;

  84.     while (n--)
  85.     {
  86.         x = 5000;
  87.         while (x--);
  88.     }
  89. }

  90. // 串口中断处理函数 (串口接收到数据,发送数据完毕都可以引起串口中断)
  91. void uart_interrupt(void) interrupt 4         //也叫串行中断服务程序
  92. {
  93.     unsigned char recv_data;// 用来存放接收到的数据
  94.    
  95.     if(RI) //接收数据(1字节)完毕,RI会被硬件置1
  96.     {
  97.         RI = 0;                    // 将接收中断标志位 清零(让串口可以继续接收数据)
  98.         recv_data = SBUF;               //读取接收到的数据,并存放到data

  99.         if(recv_data == '1')//如果收到的字符是'0',就让灯灭
  100.         {
  101. //            ShowResult(0);              //显示通道4
  102.             addA = 1;
  103.             addB = 0; //  引脚低电平,LED灯1亮
  104.         }
  105.         else if(recv_data == '2')//如果收到的字符是'0',就让灯灭
  106.         {
  107. //            ShowResult(0);
  108.             addA = 0;
  109.             addB = 1;//  引脚低电平,LED灯2亮
  110.         }
  111.     else if(recv_data == '3')//如果收到的字符是'0',就让灯灭
  112.         {
  113. //            ShowResult(0);
  114.             addA = 1;
  115.             addB = 1;//  引脚低电平,LED灯3亮
  116.         }
  117.     }
  118.     if(TI)// 发送数据(1字节)完毕
  119.     {
  120.         TI = 0;// 将 发送中断标志位 清零(让串口可以继续发送数据)
  121.     }
  122. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:258566 发表于 2021-10-20 18:41 | 只看该作者
void SendData(BYTE dat)
{
    while (!TI);                    //等待前一个数据发送完成
    TI = 0;                         //清除发送标志
    SBUF = dat;                     //发送当前数据
}
回复

使用道具 举报

板凳
ID:213173 发表于 2021-10-20 20:47 | 只看该作者
楼主这个程序是在STC官方ADC示例的基础上添加了串口接收中断函数。ADC转换结果通过串口发送上位机,并不能通过串口中断控制addA和addB亮灭。上位机必须下发'1'、'2'、'3'才能使单片机控制addA和addB亮灭。
回复

使用道具 举报

地板
ID:973635 发表于 2021-10-20 20:47 | 只看该作者
cccc888 发表于 2021-10-20 18:41
void SendData(BYTE dat)
{
    while (!TI);                    //等待前一个数据发送完成

?什么意思呢
回复

使用道具 举报

5#
ID:973635 发表于 2021-10-20 21:01 | 只看该作者
wulin 发表于 2021-10-20 20:47
楼主这个程序是在STC官方ADC示例的基础上添加了串口接收中断函数。ADC转换结果通过串口发送上位机,并不能 ...

对啊对啊那我应该怎么改鸭,我比较小白
回复

使用道具 举报

6#
ID:123289 发表于 2021-10-21 13:58 | 只看该作者
35.    while (1)
36.    {
37.             ShowResult(0);              //显示通道0
38.    }
36,37之间增加一个标记BJ1判断,当BJ1为真时,再做 ShowResult(0),否则不做。理由:
1、当数据无变化时,多次显示同样的数据无意义。
2、如果数据变化未稳定,则显示异常。
3、在需要显示的时候(如:ADC有变化了),置位BJ1,是可以办到的。              
回复

使用道具 举报

7#
ID:123289 发表于 2021-10-21 14:07 | 只看该作者
58.    while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成
如果发生意外,等不到,则会死机。这是替在的危险,而且极不易查出来。
回复

使用道具 举报

8#
ID:123289 发表于 2021-10-21 14:11 | 只看该作者
86.void SendData(BYTE dat)
87.{
88.    while (!TI);                    //等待前一个数据发送完成
89.    TI = 0;                         //清除发送标志
90.    SBUF = dat;                     //发送当前数据
程序有死在88句的危险!
91.}
回复

使用道具 举报

9#
ID:973635 发表于 2021-10-21 16:26 | 只看该作者
yzwzfyz 发表于 2021-10-21 14:11
86.void SendData(BYTE dat)
87.{
88.    while (!TI);                    //等待前一个数据发送完成

为什么灯在打开串口的时候不亮了呢,串口中断无法控制1.3和1.5管脚的高低电平
回复

使用道具 举报

10#
ID:973635 发表于 2021-10-21 16:27 | 只看该作者
yzwzfyz 发表于 2021-10-21 14:11
86.void SendData(BYTE dat)
87.{
88.    while (!TI);                    //等待前一个数据发送完成

因为我之前有单独用串口中断控制led灯亮灭的,加了ADC采集就不行了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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