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- void LED_init()
- {
- GPBCON |= 1<<3;
- }
复制代码 2.定时器初始化- void timer_init()
- {
- TCFG0 = 0x73; //预分频值115
- TCFG1 = 0x30; //分频值16
- TCMPB1 = 0x00000000;
- TCNTB1 = 0x000000ff;
- TCON |= (1<<9);
- TCON = 0x00000d00;
- }
复制代码 3.中断处理函数- void timer1_handler()
- {
- static unsigned char pwm_index = 0;
- static unsigned char period_cnt = 0;
- period_cnt++;
- if(period_cnt >= 10)
- {
- //10次中断更新一次TCMPB1的值
- TCMPB1 = indexWave[pwm_index];
- pwm_index++;
- if( pwm_index >= 40)
- {
- pwm_index=0;
- }
- period_cnt=0;
- }
- //清除中断标志位
- SRCPND1 = 1 << INTOFFSET1;
- INTPND1 = INTPND1;
- }
复制代码 4. 主函数:- void main()
- {
- LED_init(); //初始化LED
- int_initialize(); //初始化中断控制器并开启中断
- int_register(1, 11, timer1_handler); //注册Timer1中断函数
- timer_init(); //初始化Timer1并开始计数
- while(1);
- }
复制代码 打开串口软件,按住空格,开发板上电,输入loady 0x00000000 发送完make之后生成的app.bin文件后。go 0x00000000就能看到呼吸灯现象了。
视频、图片就不晒了,有需要的朋友下载源码包观察吧。
论坛ID:fjjjnk1234
提交时间:2014.07.29