原来是想把这一篇写到寄存器的解析; 后来研究了一下线路发现这片开发板的设计不是 MCU 直接接续的!中间还加了两颗逻辑元件: 74HC138 和 74HC595. 对于没有学过电子电路/逻辑电路的人,看的时候会有负担。所以,先写 函式的应用,下一篇再写到寄存器。
打开第 12 个实验 ”实验12 数码管显示实验“
按前两篇的方式把程式从 MDK 项目执行,并且编译一下: 执行的结果如下图,是 16 进制的16 个符号加上一个豆点在轮流跑。
解析主程式 Main.c
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "smg.h"
#include "timer.h"
/************************************************
************************************************/
//
//0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,
u8 smg_num[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0x01,0x00};
int main(void)
{
Stm32_Clock_Init(9); //
delay_init(72); //
uart_init(72,115200);//
LED_SMG_Init(); //
LED_Init(); //
TIM3_Init(19,7199);//
while(1)
{
}
}
u8 smg_wei=0;//
u8 smg_duan=0;//
u16 t=0;
void TIM3_IRQHandler(void)//
{
if(TIM3->SR&0X0001)//
{
LED_Write_Data(smg_num[smg_duan],smg_wei);//
LED_Refresh();//
smg_wei++;
if(smg_wei==8) smg_wei=0;
t++;
if(t==500)//
{
t=0;
LED0=!LED0;
smg_duan++;
if(smg_duan==18) smg_duan=0;
}
}
TIM3->SR&=~(1<<0);//
}
整个程式包含了几个部分:
- 含入 header 档:这些内容留到下一篇讨论。
- 变数定义: 里面比较重要的是”字型定义“ 的 smg_num[]。
- main() 主程式:我们可以看到 main()在几个寄存器初始化完毕后就没动作了。
- 时钟中断 TIM3_IRQHandler():这个是整个程式的运作中心,这一篇主要就是要讨论这个部分,并且修改成我们想要的运用。
解析中断程式 TIM3_IRQHandler()
这个中断程式包含 二块,第一块是:
LED_Write_Data(smg_num[smg_duan],smg_wei);//
LED_Refresh();//
smg_wei++;
if(smg_wei==8) smg_wei=0;
t++;
TIM3->SR&=~(1<<0);//
第二块是: 这一段是做显示的收尾工作,每 500 单位一次。
if(t==500)//
{
t=0;
LED0=!LED0; // GPIOC 的红色 LED,第”0“ bit 亮 或 暗
smg_duan++; //输出下一个字
if(smg_duan==18) smg_duan=0;// smg_num[] 有 18组字型,轮流播放一次
}
开始修改内容及测试
我做了下列动作
- 加了一个新的字串阵列 smg_dash[] 置换掉原来的 smg_num[].
- smg_wei 暂时不动
u8 smg_dash[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x01,0x00};
u8 smg_wei=0;//
u8 smg_duan=0;//
u16 t=0;
void TIM3_IRQHandler(void)//TIM3 interrupt
{
if(TIM3->SR&0X0001)//
{
LED_Write_Data(smg_dash[smg_duan],smg_wei);//
LED_Refresh();//
smg_wei++;
if(smg_wei==8) smg_wei=0;
t++;
if(t==300)//
{
t=0;
LED0=!LED0;
smg_duan++;
if(smg_duan==10) smg_duan=0;
}
}
TIM3->SR&=~(1<<0);//清除中断旗标
}
八个字一起改变!如下面照片。
- smg_wei 移动到 t==500 之后
void TIM3_IRQHandler(void)//TIM3 interrupt
{
if(TIM3->SR&0X0001)//
{
LED_Write_Data(smg_dash[smg_duan],smg_wei);//
LED_Refresh();//
t++;
if(t==300)//
{
t=0;
LED0=!LED0;
smg_wei++;
if(smg_wei==20) smg_wei=0;
smg_duan++;
if(smg_duan==20) smg_duan=0;
}
}
TIM3->SR&=~(1<<0);//
}
会跑的棒子
这一次再改动大一点!
- 增加 smg_dash_runner[] 取代 smg_dash,以及 smg_wei_runner[]。
- 修改
LED_Write_Data(smg_dash[smg_duan],smg_wei);
成为
LED_Write_Data(smg_dash_runner[smg_duan],smg_wei_runner[smg_wei]);`
- 把 ”smg_wei==“ 的值改成 20,”smg_duan==“ 的值改成 20;因为新增的字型阵列是 20 组。
结果像下面的资料
u8 smg_dash_runner[]={0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
0x20,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80};
u8 smg_wei_runner[]={0,0,0,1,2,3,4,5,6,7,7,7,7,6,5,4,3,2,1,0};
void TIM3_IRQHandler(void)//TIM3 interrupt
{
if(TIM3->SR&0X0001)//
{
LED_Write_Data(smg_dash_runner[smg_duan],smg_wei_runner[smg_wei]);//
LED_Refresh();//
t++;
if(t==100)//
{
t=0;
LED0=!LED0;
smg_wei++;
if(smg_wei==20) smg_wei=0;
smg_duan++;
if(smg_duan==20) smg_duan=0;
}
}
TIM3->SR&=~(1<<0);//清除中断旗标
}
完成后,你可以看到一根红棒子,以逆时针的方式跑动。 这两个实验跑完了的时候,我可以看到 a. 每一根字节对应的 bit 位置:bit 0 是右下角的点、bit 1 是中间的横杠,,。 b. 整个显示器的位置是“0“ 在左边,”7“ 在右边。 c.我们把”runner“ 字串阵列改成 8 组,然后填入要显示的资料在相对位置,就可以显示固定的资料出来了
—下一篇待续
|