OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6751|回复: 11

定时器中断Timer里控制LCD显示,会有杂点出现在LCD上

[复制链接]

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
发表于 2011-11-9 22:12:03 | 显示全部楼层 |阅读模式
1. main函数里执行LCD_Clear(LIGHTBLUE),将LCD画成LIGHTBLUE颜色;
2. 按照定时器中断例子,main函数初始化Tim3: Timerx_Init(5000,7199);
3. 中断处理函数 void TIM3_IRQHandler(void)
{                 
 if(TIM3->SR&0X0001)//溢出中断
 {
   LCD_ShowString(40, 40, "Tim3");                           
 }      
 TIM3->SR&=~(1<<0);//清除中断标志位     
}

4. main函数
int main(void)
{
 Stm32_Clock_Init(9);//系统时钟设置
 delay_init(72);  //延时初始化
  LCD_Init();
  LCD_Clear(LIGHTBLUE);
 Timerx_Init(5000,7199);
 while(1)
 {  
LCD_ShowString(20, 20, "Main");
 }
}

现在出现的状况是Timer里显示的"Tim3"字串周围有很多杂点。
这是什么原因啊?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165537
金钱
165537
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-9 22:31:46 | 显示全部楼层
回复【楼主位】smithlin:
---------------------------------
这个你要一步步看看了.
单独在main里面调用LCD_ShowString(40, 40, "Tim3");                           
会有杂点么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
 楼主| 发表于 2011-11-10 08:20:38 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
1. 单独在main里面调用LCD_ShowString(40, 40, "Tim3");                            
会有杂点么?
***单独调用不会有杂点

2. 如果main里的LCD_ShowString(20, 20, "Main");不是while(1)循环,也不会有杂点

3. 我的理解:main里的LCD_ShowString(20, 20, "Main");与Tim3的LCD_ShowString(40, 40, "Tim3"); 是属于不同的时钟线程。
如果两者同时drawpiont画同一个点,可能有问题。但是我现在画的一个是从(20,20)开始,另一个是(40,40)开始,一定不会有重合的点啊。为什么会有状况呢?

4. 另外,杂点出现的位置是有规律的。LCD_ShowString(40, 40, "Tim3"); 是从(40,40)开始,高16个点,宽8*4=32个点,画的是(40,40)到(72,56)的区域。
我发现杂点都是出现在(72, Y),(X, 56)的两条直线上。真是奇怪啊。
我看了LCD_DrawPoint的函数内容,是一个点一个点画的,怎么会影响的其他的位置的?


回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165537
金钱
165537
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-10 09:24:02 | 显示全部楼层
回复【3楼】smithlin:
---------------------------------
在while(1)里面加入delay_ms(10);即可.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
 楼主| 发表于 2011-11-10 12:14:33 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
while(1)里面加入delay_ms(10),还是不行啊 

我这边试验下来的结果: 在(72, Y)有条白线 在(X, 56)上有白点。。。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165537
金钱
165537
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-10 12:43:09 | 显示全部楼层
我的加入delay_ms(10)后,问题解决.
不过有可能后续还会出现.
这个问题应该是中断频繁的打断正在执行写LCD的函数,而在中断里面他又同样调用了这个函数.
试试如下修改:
   while(1) 
{     
TIM3->CR1&=~(0x0001);    //关闭定时器3
LCD_ShowString(20,20,"Main");
TIM3->CR1|=0x0001;          //使能定时器3
delay_ms(10);     
}
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
 楼主| 发表于 2011-11-10 13:51:59 | 显示全部楼层
原子哥,我这边还是不行啊,
1。 main里面
 while(1)  
{      
TIM3->CR1&=~(0x0001);    //关闭定时器3 
LCD_ShowString(20,20,"Main"); 
TIM3->CR1|=0x0001;          //使能定时器3 
delay_ms(10);      

情况依旧。

2. 我尝试修改一下LCD_ShowString函数,保证LCD_ShowString还没有返回时,不能同时调用
LCD_ShowChar()

u8 gLCDworking=0;
void LCD_ShowString(u16 x,u16 y,const u8 *p)
{   
while(gLCDworking)
{
delay_ms(10);
}
gLCDworking=1;
printf("LCD_ShowString:%s\n", p);      
    while(*p!='\0')
    {       
        if(x>MAX_CHAR_POSX){x=0;y+=16;}
        if(y>MAX_CHAR_POSY){y=x=0;LCD_Clear(WHITE);}
        LCD_ShowChar(x,y,*p,16,0);
        x+=8;
        p++;
    }  
gLCDworking=0;
}

结果还是有白色竖线呢,这就不好解释啦,
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165537
金钱
165537
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-10 14:14:50 | 显示全部楼层
回复【7楼】smithlin:
---------------------------------
那就怪了.
jtag仿真一下吧.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
 楼主| 发表于 2011-11-10 21:28:58 | 显示全部楼层
原子,我大概找到有杂点的原因了?
1. 主线程main里的LCD_Clear(LIGHTBLUE)以及LCD_ShowString(20,20,"Main");  与Tim3里面的LCD_ShowString(40, 40, "Tim3");是并行的。
2. 也就是说main和Tim3在并行的调用:
1)LCD_SetCursor: 写寄存器R32,R33, 
2)LCD_WriteRAM_Prepare: 写寄存器R34,
3)LCD_WR_DATA(POINT_COLOR); 注意:POINT_COLOR是全局变量,

所以,当你真正LCD_WR_DATA画点的时候,R32, R33寄存器里的坐标值可能已经不是之前设置的,而被另一个线程的调用而更改了。而且POINT_COLOR是全局变量,也会是同样的状况,也可能被更改了。所以导致在不该画点的出现花点了。

针对这个问题,如果有操作系统的话,我想可以通过互斥信号量解决。
在目前这样没有系统的情况下,有没有什么解决的方法啊?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165537
金钱
165537
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-10 22:08:49 | 显示全部楼层
回复【9楼】smithlin:
---------------------------------
嗯,应该是你说的原因.
方法就是不让中断打断你.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
 楼主| 发表于 2011-11-12 22:38:38 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
原子哥,互斥的问题成功解决,上来报告一下:
1. 使用全局变量标志来保护被访问的DrawPoint,不好用,很容易就把程序弄死循环了。(具体为什么死循环我不清楚,就是白屏了,仿真看的时候那个全局变量标志一直在使用,无法跳出);
2. 使用了扩展实例uCOSII中的OS_ENTER_CRITICAL,EXPORT  OS_EXIT_CRITICAL函数,成功实现互斥。

呵呵,多谢指点。
回复 支持 反对

使用道具 举报

7

主题

26

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
250
金钱
250
注册时间
2013-3-2
在线时间
67 小时
发表于 2017-3-17 10:03:56 | 显示全部楼层
请问没有使用OS的情况下具体是怎么解决的?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-14 22:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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