[原创] HELPER2416学习笔记5——呼吸灯详解

fjjjnk1234   2014-7-29 14:07 楼主

 

HELPER2416学习笔记5——呼吸灯详解

 

 

参与HELPER2416开发板助学计划

 

 

BOSS布置的作业,交得有点晚了,抱歉。首先,先说一下我的大体思路吧,采用的是之前学习STM32的一个呼吸灯例子的思想。汇编层的代码用的是yuanlai2010分享的定时器中断的工程文件,看来有时间还得加强学习下汇编的相关知识。
从医学角度来讲,一个人吸一次气再呼一次气的时间大约为3秒(前提条件:正常人),本实验主要设计让灯从灭到亮再到灭的时间大约为3秒,并且是连续的亮灭。
(1)          本次实验用到定时器1的PWM输出。首先,必须注意将GPB1设置为TOU1,之前由于没注意这个问题,设置成Output,耽误了很长时间。

与设置定时器输入时钟频率相关的寄存器:TCFG0、TCFG1。
计算公式:定时器输入时钟频率 = PCLK / {预分频值+1}/ {分频值}

通过串口打印的信息可知:PCLK=66666666Hz所以,我将TCFG0设置为0x73,即预分频值为115。将TCFG1设置为0x30,即将定时器1的分频值设置为16。
定时器1的输入时钟频率=66666666/(115+1)/16=31919.5Hz
(2)接着设置定时器1的计数缓冲寄存器TCNTB1和比较缓冲寄存器TCMPB1。

将TCNTB1装入值:0xff即255。
用MatLab仿真出来的PWM表:(装入TCMPB1中的值)
unsigned int indexWave[] = {1,1,2,2,3,4,6,8,10,14,19,25,33,44,59,80,    107,143,191,250,250,191,143,107,80,59,44,33,25,19,14,10,8,6,4,3,2,2,1,1};
表中一共有40个数据,定时器每产生10次中断,更新TCMPB1中的值。(表中的数字250本来是255,经过实际现象观察,如果是255在要到达最亮的时候会出现闪烁,所以我改成了250,问题就解决了)
可以算出:一次呼吸周期为:(1/31919.5)*256*400=3.2秒与理论值3秒接近
(3)设置TCON寄存器

先设置TCON的第9位置1,手动将TCNTB1/TCMPB1中的值装入TCNT1/TCMP1。接着设置TCON=0x00000d00,设置定时器1自动装载、输出反转(S3C2416的定时器为向下计数,设置输出反转时,当TCNTn<=TCMPn时,输出电平为低电平)和开启定时器1。
思路大概就这样了,接着挑几个重要的函数讲解吧。
1.设置GPB1为TOUT1
  1. void LED_init()
  2.  
  3. {
  4.  
  5.         GPBCON |= 1<<3;
  6.  
  7. }
复制代码
2.定时器初始化
  1. void timer_init()
  2. {
  3.     TCFG0  = 0x73;         //预分频值115   
  4.     TCFG1  = 0x30;        //分频值16
  5.     TCMPB1 = 0x00000000;
  6.     TCNTB1 = 0x000000ff;
  7.     TCON |= (1<<9);        
  8.     TCON = 0x00000d00;   
  9. }
复制代码
3.中断处理函数
  1. void timer1_handler()
  2. {
  3.         static unsigned char pwm_index = 0;
  4.         static unsigned char period_cnt = 0;
  5.         period_cnt++;
  6.         if(period_cnt >= 10)
  7.         {
  8.                                         //10次中断更新一次TCMPB1的值
  9.                 TCMPB1 = indexWave[pwm_index];
  10.                 pwm_index++;
  11.                 if( pwm_index >=  40)
  12.                 {
  13.                         pwm_index=0;                                             
  14.                 }
  15.                 period_cnt=0;
  16.         }
  17. //清除中断标志位
  18.     SRCPND1 = 1 << INTOFFSET1;        
  19.     INTPND1 = INTPND1;                 
  20. }
  21.  
复制代码
4.  主函数:
  1.  

 

提示词:如果您需要查看本帖隐藏内容,请登录或者注册
相由心生,境随心转,一切法从心想生。

回复评论 (6)

看似小小的一个功能,实现起来也很简单,但是认真分析起来,里边还是有很多道道的!只要认真去研究,顺藤摸瓜,后边就一通百通了!给个赞!你会获得小奖品!呵呵 本帖最后由 spacexplorer 于 2014-7-29 15:08 编辑
My dreams will go on... http://www.jyxtec.com
点赞  2014-7-29 15:04
楼主真不是一般的认真~~~~~~~
点赞  2014-7-29 15:20
过来赞一个
点赞  2014-7-29 17:12
对 Matlab怎么仿真出PWM表非常感兴趣?
只对matlab做曲线拟合有点基础,怎么仿真的话应该怎么学习呢?
望LZ指点。谢谢
点赞  2014-8-6 13:12
引用: wuyongwang2345 发表于 2014-8-6 13:12
对 Matlab怎么仿真出PWM表非常感兴趣?
只对matlab做曲线拟合有点基础,怎么仿真的话应该怎么学习呢?
望 ...

其实这个PWM表是我直接利用别人仿真出来的,我也没学过MatLab
10.png
11.png
相由心生,境随心转,一切法从心想生。
点赞  2014-8-6 14:09
引用: fjjjnk1234 发表于 2014-8-6 14:09
其实这个PWM表是我直接利用别人仿真出来的,我也没学过MatLab

喔  好的 谢谢LZ分享
点赞  2014-8-6 14:22
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复