找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2513|回复: 10
收起左侧

通过单片机ADC读取电位器的值改变定时器程序调试

[复制链接]
ID:254747 发表于 2021-9-5 20:56 | 显示全部楼层 |阅读模式
其中MAN_KUAN_PIN_LV这个数据是来自ADC的   我将ADC程序放在了后面

这个程序是这样的 通过ADC读取电位器的值然后发送到这里来改变 定时器计时长度的,现在的问题是 程序运行起来只要不动电位器也就是不传入新的数据 LED就闪烁正常   当我旋转电位器   就出现LED长亮或者熄灭 过一段时间就恢复正常,
1.慢慢旋转要好点 但是还是会出现问题
2.快速旋转就马上出现问题  这样肯定是不行的  我要的结果就是随便旋转输出都要正常
3.这个问题是怎么导致的  是电位器数据丢失吗 但是用数码管测试又没有发现丢失数据都正常
4.是不是ADC传出来的数据不对导致的  
5.是不是我在改变这个值的时候需要关闭定时器   我关闭了  不行 还是一样的  
6.我将ADC函数(FU_PIN_JIE_GUO_GetADCResult())直接传入到了void    MAN_KUAN_ADJ(unsigned char MAN_KUAN_PIN_LV )这个函数里面

由于我的程序全部都是模块编程的  全部贴上来更乱  我把关键的东西贴了上来 还请大神给我看看  谢谢  我非常着急

void Timer1_Init(void)                //1毫秒@18.432MHz
{
                 EA = 1;//打开总中断
                 AUXR |= 0x40;                //定时器时钟1T模式
                 TMOD &= 0x0F;                //设置定时器模式
                 TL1 = 0x40;                  //设置定时初值
                 TH1 = 0xA2;                  //设置定时初值
                 TF1 = 0;                    //清除TF1标志
                 TR1 = 1;                    //定时器1开始计时            
                 ET1 = 1;                        // 启动定时器1中断允许位

}



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

void timer1_isr(void) interrupt 3
{

          MAN_KUAN_SHI_JIAN++;

}



void    MAN_KUAN_ADJ(unsigned char MAN_KUAN_PIN_LV )
        
{   
        
          unsigned char   TEMP_MAI_KUAN;


    TEMP_MAI_KUAN =(unsigned char) 0X3E8 / MAN_KUAN_PIN_LV*2;

                if(TEMP_MAI_KUAN == MAN_KUAN_SHI_JIAN)        
                                {
                                                        MAN_KUAN_SHI_JIAN = 0;
                                                        LED1 = ~LED1;         
                                }                        
         

}
下面是ADC程序

//准换速率是180个时钟
void ADC_INIT ()
        
{
      P1ASF |= 0X3C;                       //  将P1.2 P1.3 P1.4 P1.5口作为ADC输入信号
            ADC_RES=0;                           //清零转换结果寄存器高8位
            ADC_RESL=0;                          //清零转换结果寄存器低2位
      ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START ;  //打开电源 设置速度位180个时钟 开始转换
      Delay1ms();
            Delay1ms();                          //延时 等待电源稳定            
            Delay1ms();
            Delay1ms();
            Delay1ms();                          //延时 等待电源稳定            
            Delay1ms();
}



FU_PIN_JIE_GUO_GetADCResult()
{
        
            unsigned  int  fupingjieguo;
                        ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch2 | ADC_START;  //打开电源 速度180个时钟 选择通道2 启动转换
                        _nop_();                             //等待4个NOP
                        _nop_();
                        _nop_();
                        _nop_();
                        while (!(ADC_CONTR & ADC_FLAG));     //等待ADC转换完成  全部为1 表示转换完成
//             ADC_CONTR &= ~0X80;                  //关闭ADC电源  节约功耗
                        ADC_CONTR &= ~ADC_FLAG;              //Close ADC  清楚标识位
                        fupingjieguo = (ADC_RES<<2) + ADC_RESL;    //将高2两位  和低8位的结果相加得到10位的结果

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

            return fupingjieguo;                 //返回ADC结果
}

回复

使用道具 举报

ID:624769 发表于 2021-9-5 21:35 | 显示全部楼层
(unsigned char) 0X3E8
你这里强制 unsigned char 之后  后面全是单字节运算。即 0x3E8 直接变 0xE8 后面除法也一样。
建议不要这个 unsigned char
回复

使用道具 举报

ID:161164 发表于 2021-9-5 21:42 | 显示全部楼层
如果问题真的出现在你以为有问题的地方
你已经可以自己解決问题而不是上来问问题
所以还是乖乖的把所有代码贴上来吧
回复

使用道具 举报

ID:960726 发表于 2021-9-5 22:51 | 显示全部楼层
1、TEMP_MAI_KUAN =(unsigned char) 0X3E8 / MAN_KUAN_PIN_LV*2;可读性不好!
直接,TEMP_MAI_KUAN =2000/MAN_KUAN_PIN_LV的意思?
2、会不会是ADC没有做滤波处理;
3、 另外,这里的判断, if(TEMP_MAI_KUAN == MAN_KUAN_SHI_JIAN)必须在1mS内执行到,建议改成<=呢?
回复

使用道具 举报

ID:254747 发表于 2021-9-6 09:25 | 显示全部楼层
188610329 发表于 2021-9-5 21:35
(unsigned char) 0X3E8
你这里强制 unsigned char 之后  后面全是单字节运算。即 0x3E8 直接变 0xE8 后面 ...

这是我找不到办法了后面添加的   现在已经去掉了 谢谢哦
回复

使用道具 举报

ID:254747 发表于 2021-9-6 09:26 | 显示全部楼层
本帖最后由 不将就123 于 2021-9-6 09:44 编辑
seuww 发表于 2021-9-5 22:51
1、TEMP_MAI_KUAN =(unsigned char) 0X3E8 / MAN_KUAN_PIN_LV*2;可读性不好!
直接,TEMP_MAI_KUAN =2000/ ...

ADC里面没有滤波函数   嗯嗯  感谢  今天我回去在改进一下  但是这里只能等于 不小小于或者大于
回复

使用道具 举报

ID:139866 发表于 2021-9-6 10:24 | 显示全部楼层
乖乖贴代码吧,水平不够这点代码看不出哪里有BUG
回复

使用道具 举报

ID:254747 发表于 2021-9-6 13:52 | 显示全部楼层
天ノ忆 发表于 2021-9-6 10:24
乖乖贴代码吧,水平不够这点代码看不出哪里有BUG

好的   我今天回去吧代码整理了  全部贴上来  给大家看看   寻求一下问题  
回复

使用道具 举报

ID:624769 发表于 2021-9-6 14:08 | 显示全部楼层
unsigned  int  fupingjieguo;
fupingjieguo = (ADC_RES<<2) + ADC_RESL;    //将高2两位  和低8位的结果相加得到10位的结果
fupingjieguo = fupingjieguo/40.92;   //ad输出的结果最大是1024按照,但是只要0-25
                                                 //缩小倍率就是1023除以25就是40.92 故用1023除以40.92即可转换为25
你这个 fupingjieguo 是整形,
你下面却让他参与 浮点 计算. 得到的结果可能还没有 除以 41 来的准确。
你既然只要 0- 25 你ADC 只要取 高 8 位 就可以了,本来低二位就是误差位你不用就好了,你非把它拉进来,为了增加结果的抖动范围么??
回复

使用道具 举报

ID:254747 发表于 2021-9-7 09:33 | 显示全部楼层
188610329 发表于 2021-9-6 14:08
unsigned  int  fupingjieguo;
fupingjieguo = (ADC_RES

谢谢大师指导,通过这两天不断找问题 ,你说的这个现象很有可能  ,我今天下班测试一下 , 目前看到的问题  可能就是ADC在传数据到中断函数的时候出问题了 ,   程序下载进去以后, 通电测试, 当快速旋转电位器就会导致中断无法正常工作 LED长亮或者熄灭 , 同时高概率出现上电就 进入中断函数, 然后哪个LED灯一直亮, 就好像是定时器没有定时一样, 或许和你说的有关, 可能就是ADC电位器的值在上电的时间丢失了导致定时器不知道,定时多久,出现了LED长亮的现象。
回复

使用道具 举报

ID:213173 发表于 2021-9-7 10:44 | 显示全部楼层
本帖最后由 wulin 于 2021-9-7 10:49 编辑

不知楼主用ADC控制定时器的周期在多长时间范围。按一般思路,定时器用8位自动重载模式,ADC取8位精度,直接用ADC_RES结果赋值TH1,如果要缩小ADC取值范围可以在电位器串联合适的分压电阻即可。楼主把非常简单的事情搞得这么复杂,根本用不着浮点去算这么简单的数据。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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