找回密码
 立即注册

QQ登录

只需一步,快速开始

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

这个单片机程序进入中断以后,主程序就无法运行了

[复制链接]
跳转到指定楼层
楼主
ID:254747 发表于 2021-9-3 19:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序中的这个FU_PIN_JIE_GUO_GetADCResult()是ADC准换电位器的值  直接写入到PCA里面来调节频率的   当发生中断以后  主程序的类容就不在显示了  数码管全部都是瞎子了  麻烦大神给我看看       在中断这方面我都不是很熟悉  不敢使用

单片机源程序如下:
  1. #include <STC15F2K60S2.H>
  2. #include "intrins.h"


  3. //AD延时
  4. void Delay1ms()                //@24.000MHz
  5. {
  6.         unsigned char i, j;

  7.         i = 24;
  8.         j = 85;
  9.         do
  10.         {
  11.                 while (--j);
  12.         } while (--i);
  13. }



  14. //数码管延时
  15. void Delay100us()                //@24.000MHz
  16. {
  17.         unsigned char i, j;

  18.         i = 3;
  19.         j = 82;
  20.         do
  21.         {
  22.                 while (--j);
  23.         } while (--i);
  24. }





  25. #define ADC_POWER   0x80          //ADC电源控制位
  26. #define ADC_FLAG    0x10          //ADC完成标志
  27. #define ADC_START   0x08          //ADC起始控制位
  28. #define ADC_SPEEDLL 0x40          //180个时钟

  29. unsigned char ch2 = 0X02;         //通道选择变量 0x02;选择P1.2
  30. unsigned char ch3 = 0X03;         //选择P1.3
  31. unsigned char ch1 = 0X04;                                        //选择P1.4
  32. unsigned int   TL,TH;
  33. //unsigned int  jie_guo;
  34. unsigned fupingjishu = 0;

  35. void ADC_INIT ();
  36. void PCA_REG_PWM();
  37. void PCA_PIN_LV_ADJ(unsigned char );
  38. void Timer0Init(void);
  39. void INT0_TEST();
  40. void Timer1_Init(void);


  41. ZHU_PIN_JIE_GUO_GetADCResult();
  42. FU_PIN_JIE_GUO_GetADCResult();
  43. ZHAN_KONG_BI_JIE_GUO_GetADCResult();



  44. //连接138译码器  
  45. sbit   LSA = P5^1;   
  46. sbit   LSB = P5^2;
  47. sbit   LSC = P5^3;
  48. sbit   LED1 = P0^3;

  49. //0-9 数码段位显示数字
  50. unsigned  code   sumaguan_duan[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};     

  51. //位选信号
  52. unsigned  char  displaydata[7] ;   //用来保存分离出来的数据
  53. void  shu_ma_guan();
  54. void  shumaguan_shuju_chuli(unsigned int zhupin,unsigned char fupin,unsigned char fupin_zhankongbi);

  55. main()
  56. {
  57.         
  58.      ADC_INIT ();
  59.            PCA_REG_PWM();
  60.            Timer0Init();
  61.            Timer1_Init();
  62.            P5M0        =   0x00;   //0000,0000 端口5模式寄存器0
  63.      P5M1        =   0x00;   //0000,0000 端口5模式寄存器1
  64.      P4M0        =   0x00;   //0000,0000 端口4模式寄存器0  数码管用
  65.      P4M1        =   0x00;
  66.            P1M0        =   0x00;   //
  67.      P1M1       |=   0x04;   //  设置P1.2为高阻输入模式
  68.            P0M0        =   0x00;   //0000,0000 端口4模式寄存器0  数码管用
  69.      P0M1        =   0x00;
  70.     while (1)
  71.                 {
  72.                         //数码管驱动函数
  73.                   shu_ma_guan();
  74.                         //数码管数据接收函数
  75.         shumaguan_shuju_chuli(ZHU_PIN_JIE_GUO_GetADCResult(),FU_PIN_JIE_GUO_GetADCResult(),ZHAN_KONG_BI_JIE_GUO_GetADCResult());
  76.                   //设置占空比
  77.                         CCAP0H = CCAP0L = ZHAN_KONG_BI_JIE_GUO_GetADCResult();   
  78.                         //设置频率
  79.                         PCA_PIN_LV_ADJ(FU_PIN_JIE_GUO_GetADCResult() );         
  80.          
  81.                 }



  82. }


  83. // ADC初始化
  84. void ADC_INIT ()
  85.         
  86. {
  87.       P1ASF |= 0X1C;                       //  将P1.2 P1.3 P1.4 口作为ADC输入信号
  88.             ADC_RES=0;                           //清零转换结果寄存器高8位
  89.             ADC_RESL=0;                          //清零转换结果寄存器低2位
  90.       ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START ;
  91.       Delay1ms();
  92.             Delay1ms();
  93.             Delay1ms();
  94.             Delay1ms();
  95.             
  96. }

  97. //高频结果转换  P1.2
  98. ZHU_PIN_JIE_GUO_GetADCResult()
  99. {
  100.         
  101.            unsigned  int  zhupinjieguo;
  102.                         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch1 | ADC_START;  //打开电源 速度180个时钟 选择通道2 启动转换
  103.                         _nop_();                             //等待4个NOP
  104.                         _nop_();
  105.                         _nop_();
  106.                         _nop_();
  107.                         while (!(ADC_CONTR & ADC_FLAG));     //等待ADC转换完成  全部为1 表示转换完成
  108.              ADC_CONTR &= ~0X80;                  //关闭ADC电源  节约功耗
  109.                         ADC_CONTR &= ~ADC_FLAG;              //Close ADC  清楚标识位
  110.                         zhupinjieguo = (ADC_RES<<2) + ADC_RESL;    //将高2两位  和低8位的结果相加得到10位的结果

  111.       zhupinjieguo = zhupinjieguo/3.41;                //ad输出的结果最大是1024按照,但是只要0-300
  112.                                                  //缩小倍率就是1023除以300就是3.41 故用1023除以3.41即可转换为300

  113.             return zhupinjieguo;                       //返回ADC结果
  114. }
  115. //PCA_PWM_频率控制结果 P1.3
  116. FU_PIN_JIE_GUO_GetADCResult()
  117. {
  118.         
  119.            unsigned  int  fupingjieguo;
  120.                         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch2 | ADC_START;  //打开电源 速度180个时钟 选择通道2 启动转换
  121.                         _nop_();                             //等待4个NOP
  122.                         _nop_();
  123.                         _nop_();
  124.                         _nop_();
  125.                         while (!(ADC_CONTR & ADC_FLAG));     //等待ADC转换完成  全部为1 表示转换完成
  126.              ADC_CONTR &= ~0X80;                  //关闭ADC电源  节约功耗
  127.                         ADC_CONTR &= ~ADC_FLAG;              //Close ADC  清楚标识位
  128.                         fupingjieguo = (ADC_RES<<2) + ADC_RESL;    //将高2两位  和低8位的结果相加得到10位的结果

  129.             fupingjieguo = fupingjieguo/40.92;   //ad输出的结果最大是1024按照,但是只要0-25
  130.                                                  //缩小倍率就是1023除以25就是40.92 故用1023除以40.92即可转换为25

  131.             return fupingjieguo;                 //返回ADC结果
  132. }
  133. //PCA_PWM占空比结果  P1.4
  134. ZHAN_KONG_BI_JIE_GUO_GetADCResult()
  135. {
  136.         
  137.            unsigned  int  zhankongbijieguo;
  138.                         ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch3 | ADC_START;  //打开电源 速度180个时钟 选择通道2 启动转换
  139.                         _nop_();                             //等待4个NOP
  140.                         _nop_();
  141.                         _nop_();
  142.                         _nop_();
  143.                         while (!(ADC_CONTR & ADC_FLAG));     //等待ADC转换完成  全部为1 表示转换完成
  144.              ADC_CONTR &= ~0X80;                  //关闭ADC电源  节约功耗
  145.                         ADC_CONTR &= ~ADC_FLAG;              //Close ADC  清楚标识位
  146.                         zhankongbijieguo = (ADC_RES<<2) + ADC_RESL;    //将高2两位  和低8位的结果相加得到10位的结果

  147.             zhankongbijieguo = zhankongbijieguo/4;       //ad输出的结果最大是1024按照,但是占空比只要0-98可调
  148.                                                             //缩小倍率就是1023除以100就是10.43 故用1023除以10.43即可转换为98

  149.             return zhankongbijieguo;                        //返回ADC结果
  150. }

  151. //数码管显示屏函数 初始化函数
  152. void  shu_ma_guan()
  153. {
  154.      unsigned  char  i;

  155.                  for(i=0;i<7;i++)    //0 1 2 3 4 5 6
  156.                                  {
  157.                                                         switch(i)         //位选,选择点亮的数码管,
  158.                                                         {
  159.                                                                         case(0):
  160.                                                                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  161.                                                                         case(1):
  162.                                                                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  163.                                                                         case(2):
  164.                                                                                 LSA=0;LSB=1;LSC=0; break;//显示第2位
  165.                                                                         case(3):
  166.                                                                                 LSA=1;LSB=1;LSC=0; break;//显示第3位
  167.                                                                         case(4):
  168.                                                                                 LSA=0;LSB=0;LSC=1; break;//显示第4位
  169.                                                                         case(5):
  170.                                                                                 LSA=1;LSB=0;LSC=1; break;//显示第5位
  171.                                                                         case(6):
  172.                                                                                 LSA=0;LSB=1;LSC=1; break;//显示第6位
  173.                                                         }
  174.                                                                                                 
  175.                                                                          P4=displaydata[ i];
  176.                                                                          Delay100us();
  177.                                                                          P4 = 0X00;   //消影信号
  178.                                  }

  179.             
  180. }

  181. //数码管 数据接收与处理函数
  182. void  shumaguan_shuju_chuli(unsigned int zhupin,unsigned char fupin,unsigned char fupin_zhankongbi)
  183. {
  184. //       //低频频率
  185.                displaydata[0] = sumaguan_duan[fupin/10%10];
  186.                displaydata[1] = sumaguan_duan[fupin%10];
  187.             
  188.             
  189. //             //低频占空比
  190.                displaydata[2] = sumaguan_duan[fupin_zhankongbi/10%10];
  191.                displaydata[3] = sumaguan_duan[fupin_zhankongbi%10];
  192.         
  193.                                         //主频频率
  194.                                  displaydata[4] = sumaguan_duan[zhupin/100%10];
  195.                                  displaydata[5] = sumaguan_duan[zhupin/10%10];
  196.                                  displaydata[6] = sumaguan_duan[zhupin%10];
  197.         
  198. }

  199. //PCA_PWM寄存器配置
  200. void PCA_REG_PWM()
  201. {
  202.         
  203.            //ACC = P_SW1;
  204.      //ACC &= ~(CCP_S0 | CCP_S1);  //外设端口切换寄存器1
  205.      //P_SW1 = ACC;                //本次不需要切换端口
  206.   
  207.      CMOD |=0X04;   //1、CPS2、CPS1、CPS0系统时钟,定时器0的溢出 脉冲
  208.                     //2、当CIDL=0时, 空闲模式下PCA计数器继续工作;
  209.                           //允许ECF溢出中断
  210.         
  211.      CCON &=0X00;   //不需要中断标志位和中断溢出所以并且初始化的时
  212.                     //候需要关闭PWM所以全部设置位0        
  213.         
  214.            CCAPM0 |=0X42; //允许比较器功能控制位  允许脉宽调节模式    P1.1
  215.                     //ECOM0:允许比较器功能控制位。 允许比较器
  216.                     //CAPP0: 正捕获控制位。        不允许
  217.                     //CAPN0:负捕获控制位。         不允许
  218.                                                                                 //MAT0: 匹配 控制位 。         不允许
  219.                                                                                 //TOG0: 翻转控制位。           不允许
  220.                                                                                 //PWM0: 脉宽调节模式           允许
  221.                                                                                 //ECCF0: 使能CCF0中断          不允许
  222.         
  223. //    CCAPM1 |=0X42; //同上                                      P1.0
  224.                  
  225.            CL = 0;        //低位初值设置为0
  226.            CH = 0;        //高位初值设置为0
  227.                  
  228.            CCAP0H = CCAP0L = 0x80;   //PWM    设置占空比为50%                              
  229.                                           
  230. //           CCAP1L = 0x80;   //PWM    设置占空比为50%                                   
  231. //           CCAP1H = 0x60;   //PWM    设置占空比为50%
  232.                  
  233.            PCA_PWM0 = 0X00; //PCA模块0工作于8位PWM功能
  234. //     PCA_PWM1 = 0X00; //PCA模块1工作于8位PWM功能                 
  235.      CR = 1 ;

  236. }

  237. //定时器0溢出  设置PCA时钟用于调节频率
  238. void   Timer0Init(void)
  239. {

  240.                                 AUXR |= 0x80;                //定时器时钟1T模式
  241.                                 TMOD &= 0xF0;                //设置定时器模式
  242.                                 TL0 = 0xA0;                //设置定时初值
  243.                                 TH0 = 0xF6;                //设置定时初值
  244.                                 TF0 = 0;                //清除TF0标志
  245.                                 TR0 = 1;                //定时器0开始计时

  246. }


  247.   //频率更新函数
  248. void PCA_PIN_LV_ADJ(unsigned char fuping)
  249. {
  250.         unsigned long  temp;

  251.         //重新初始化定时初值
  252.         temp = 0x10000-24000000/(fuping*256) ;
  253.         TH0 =TH= temp>>8;                //设置定时初值
  254.         TL0 =TL= temp;                  //设置定时初值


  255. }



  256. void Timer1_Init(void)                //1毫秒@18.432MHz
  257. {
  258.         AUXR |= 0x40;                //定时器时钟1T模式
  259.         TMOD &= 0x0F;                //设置定时器模式1
  260.         TMOD |= 0x10;                //设置定时器模式
  261.         TL1 = 0x00;                    //设置定时初值
  262.         TH1 = 0xB8;                    //设置定时初值
  263. //        TF1 = 0;                    //清除TF1标志
  264.         TR1 = 1;                    //定时器1开始计时


  265.         EA = 1;             //打开总中断
  266.         ET1 = 1;                        // 启动定时器1中断允许位




  267. }


  268. /*-------------------------------------
  269. 功能:定时器1 中断服务程序
  270. 介绍:中断程序无需声明
  271. --------------------------------------*/

  272. void timer1_isr(void) interrupt 3
  273. {
  274.       
  275.    if(TF1 == 1        );
  276.          
  277.             TF1 = 0;        
  278.                    TR1 = 0;
  279.                                                  TL1 = 0x00;                //设置定时初值
  280.                                                  TH1 = 0xB8;                //设置定时初值
  281.                                                  TR1 = 1;

  282.                                         fupingjishu++;
  283.                                        
  284.                                         if(1000/FU_PIN_JIE_GUO_GetADCResult()/2 == fupingjishu)        //(Sd_Key_Value2*10)
  285.                                                 {
  286.                                                                         fupingjishu = 0;
  287.                                                                         LED1 = ~LED1;           //测试用   接示波器 查看副频波形
  288.                                                                         
  289.                                                          
  290.                                                 }
  291.                                          
  292.                                        
  293. }
复制代码


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

使用道具 举报

沙发
ID:878061 发表于 2021-9-3 21:29 | 只看该作者
if(TF1 == 1        );这个分号先去掉
回复

使用道具 举报

板凳
ID:254747 发表于 2021-9-3 21:38 | 只看该作者
huashanhui20 发表于 2021-9-3 21:29
if(TF1 == 1        );这个分号先去掉

嗯嗯  我去掉了还是一样的   反正就是程序只要进入中断   数码管的函数 也就是while里面全部,没有用了
回复

使用道具 举报

地板
ID:254747 发表于 2021-9-3 21:42 | 只看该作者
huashanhui20 发表于 2021-9-3 21:29
if(TF1 == 1        );这个分号先去掉

程序比较乱   不知道怎么回事  发上来就乱了 还是非常感谢你能耐心的看完并且给我解答

我在中断里面处理的ADC转换过来的电位器数字开始运行还可以 后面一下就么有反应了  
回复

使用道具 举报

5#
ID:195446 发表于 2021-9-3 21:42 | 只看该作者
中断函数里 if (TF1==1)去掉。
回复

使用道具 举报

6#
ID:254747 发表于 2021-9-4 10:24 | 只看该作者
mffhxa 发表于 2021-9-3 21:42
中断函数里 if (TF1==1)去掉。

这个是 我最后添加的  查询了一下  去掉和不去掉都是一样的   
回复

使用道具 举报

7#
ID:94031 发表于 2021-9-4 11:05 | 只看该作者
把定时中断的间隔要加大,不然中断太频繁,cpu就没时间处理显示与其他事情了。
回复

使用道具 举报

8#
ID:624769 发表于 2021-9-4 14:55 | 只看该作者
       TMOD |= 0x10;                //设置定时器模式
为16位不重载模式,
看你中断里面,又再次赋值 相同的 TH1, TL1 那么,为什么不直接设置为 16 位 自动重载呢?
然后,由于不重载,你先清TF1 会有一定的问题,建议你不要手动清除TF1, 中断结束后,会自动清的,实在强迫症要手动清除,最好在退出中断前清除。同时TR1 也不要中断里开开关关的。
最后 STC15系列的 T1 有各种不稳定问题。很多型号都直接没有 T1, 只有T0,T2, 早期的STC15F104E 这一系列有T1的都直接停产了, 直接出了后面 STC15F104W,改用 T2, 就明白为啥了, 测试的时候尽量避开 T1, 等你程序都理顺了,再尝试T1 可能更好。
回复

使用道具 举报

9#
ID:254747 发表于 2021-9-4 16:23 | 只看该作者
188610329 发表于 2021-9-4 14:55
TMOD |= 0x10;                //设置定时器模式
为16位不重载模式,
看你中断里面,又再次赋值  ...

好的 谢谢  我今天回去在尝试一下     我用的是STC15W4K32这个片子 不知道有什么问题没有   谢谢你的解答   关于你给我提的这个问题  我最开始是参考手册配置的   在中断里面没有那些乱七八糟的后来调试的时候弄进去的  我发上来的时候忘记整理这里了    非常感谢   我今天回去按你回复的在尝试 一下   
回复

使用道具 举报

10#
ID:254747 发表于 2021-9-5 09:24 | 只看该作者
经过我再次 查看程序 和调试的时候发现  出现这个问题可以能是 定时器1 和定时器0干仗了   冲突了   当我把主程序的 PCA_PIN_LV_ADJ(FU_PIN_JIE_GUO_GetADCResult() );    屏蔽了以后 中断方面就正常了   
我仔细查看了一下 这个调语句每次都会来处理定时器0的溢出时钟频率供给PCA作为时钟信号输出PWM信号 每次都在这里耽误了时候     让我很头疼   我现在把这两个定时器都改成了 自动重装   以前我也写过类似的程序但是也用了两个定时器是STC12的片子 没有出现类似的问题  但是哪个程序的定时器用的是手动重装   而且显示用的是1602   这个用的是数码管     并且没有这么多ADC转换   不知道是不是ADC转换也导致了这样的问题
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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