基于LMS8962的跑马灯教学程序——定时器、串口及GPIO的使用
2010-06-18 22:32
441 查看
一、电路原理图
#define LEDs GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2
控制代码如下:
GPIOPinWrite(GPIO_PORTA_BASE, LEDs, temp<<2);
此处,temp左移2位,是使得temp的低四位可以对齐至PIN5,PIN4,PIN3,PIN2。
二、功能要求
(1)闪灭时间1s;(2)起始状态LED3、LED4、LED5、LED6全灭;
(3)走马灯流程。
a.LED3亮(其他三灯灭)->LED4亮(其他三灯灭)->
LED5亮(其他三灯灭)->LED6亮(其他三灯灭)
b.四灯由灭到亮,由亮到灭闪烁4次
c.LED6亮(其他三灯灭)->LED5亮(其他三灯灭)->
LED4亮(其他三灯灭)->LED3亮(其他三灯灭)
d.继续流程b
如若定义状态编码如下:
LED6 | LED5 | LED4 | LED3 |
MSB(0,灭;1,亮) | (0,灭;1,亮) | (0,灭;1,亮) | (0,灭;1,亮)LSB |
则每秒的状态如下所示:
三、功能实现
3.1 使用查询方式
从功能要求中,可以看到,此走马灯可以分为三种基本状态:LED点亮顺序由小到大(即LED3->LED4->…………)
四灯同闪4次
LED点亮顺序由大到小(即LED6->LED5->…………)
因此设计三个函数完成以上3项功能:
3.1.1 ShiftUp
void ShiftUp(){
int i = 0;
unsigned char temp = 0;
for(i = 0; i <=3; i++){
temp = ~(0x01<
GPIOPinWrite(GPIO_PORTA_BASE, LEDs, temp<<2);
SysCtlDelay(1000* (TheSysClock / 3000)); // 延时约1s
}
}
3.1.2 ShiftDown
void ShiftDown(){
int i = 0;
unsigned char temp = 0;
for(i = 0; i <=3; i++){
temp = ~(0x08>>i);
GPIOPinWrite(GPIO_PORTA_BASE, LEDs, temp<<2);
SysCtlDelay(1000* (TheSysClock / 3000)); // 延时约1s
}
}
3.1.3 Blinky
void Blinky(){int i = 0;
for(i = 0; i <=3; i++)
{
GPIOPinWrite(GPIO_PORTA_BASE, LEDs, 0x00<<2);//亮
SysCtlDelay(1000* (TheSysClock / 3000)); // 延时约1s
GPIOPinWrite(GPIO_PORTA_BASE, LEDs, 0xFF<<2);//灭
SysCtlDelay(1000* (TheSysClock / 3000)); // 延时约1s
}
}
3.1.4 主程序
void main(){
SysClkInit();
PortAInit();
while(1)
{
ShiftUp();
Blinky();
ShiftDown();
Blinky();
}
}
3.2 使用定时器中断方式
3.2.1 初始化Timer0A
void TimerAInit()
{
/* 使能定时器0外设 */
SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER0 );
/* 使能全局中断 */
IntMasterEnable();
/* 使能Timer0中断 */
GPIOPinTypeTimer(TIMER0_BASE, TIMER_A);
/* 设置定时器0为周期触发模式 */
TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
/* 设置定时器装载值:定时1/2秒 */
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet());
/* 设置定时器为溢出中断 */
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
/* 使能定时器0 */
TimerEnable(TIMER0_BASE, TIMER_A);
/* 使能定时器0外设 */
IntEnable(INT_TIMER0A);
}
3.2.2 Timer0A中断服务程序
void Timer0A_ISR (void){
unsigned char temp = 0;
/* 清除定时器0中断 */
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
switch (status)
{
case 1:
temp = ~(0x01 << index);
index ++;
if(index == 4)
{
preStatus = 1;
status = 2;
index = 0;
}
break;
case 2:
if(index%2)
temp = ~(0x00);
else
temp = ~(0x0f);
index ++;
if(index == 8)
{
if(preStatus == 1)
status = 3;
else
status = 1;
index = 0;
}
break;
case 3:
temp = ~(0x08 >> index);
index ++;
if(index == 4)
{
preStatus = 3;
status = 2;
index = 0;
}
break;
default:
status = 1;
index = 0;
break;
}
GPIOPinWrite(GPIO_PORTA_BASE, LEDs, temp<<2);
/* 使能定时器0 */
TimerEnable(TIMER0_BASE, TIMER_A);
}
由于中断服务程序每秒进入一次,因此,需要记录每次进入中断服务时LED运行的状态,该状态由走马灯运行阶段status,某运行阶段累计次数index,以及preStatus决定。此三个变量定义为全局变量,如下所示:
int status = 1;
int preStatus = 1;
int index = 0;
状态之间的切换顺序为:
状态1(LED从小到大依次闪过) ——>
状态2(LED闪烁4次后根据preStatus的值选择进入状态3或状态1) ——>
状态3(LED从大到小依次闪过)
3.3 发送状态编码
3.3.1 初始化UART0
#define UART0_PIN GPIO_PIN_0 | GPIO_PIN_1void Uart0Init()
{
/* 使能UART外设 */
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
/* 使能GPIOA外设 */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
/* 配置UART功能脚 */
/* 设置GPIO的A0和A1为UART引脚 */
/* (A0->RXD,A1->TXD) */
GPIOPinTypeUART(GPIO_PORTA_BASE, UART0_PIN);
/* 配置UART 为 9600波特率 8-N-1模式发送数据 */
UARTConfigSet(UART0_BASE, 9600, (UART_CONFIG_WLEN_8 |
UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
}
3.3.2 发送字符串
void UartPuts(const char *s){
while(*s != '/0')
{
UARTCharPut(UART0_BASE, *(s++));
}
}
3.3.3 Timer0A_ISR
void Timer0A_ISR (void){
char buffer[8];
unsigned char bit4;
unsigned char bit3;
unsigned char bit2;
unsigned char bit1;
unsigned char temp = 0;
/* 清除定时器0中断 */
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
switch (status)
{
case 1:
temp = ~(0x01 << index);
index ++;
if(index == 4)
{
preStatus = 1;
status = 2;
index = 0;
}
break;
case 2:
if(index%2)
temp = ~(0x00);
else
temp = ~(0x0f);
index ++;
if(index == 8)
{
if(preStatus == 1)
status = 3;
else
status = 1;
index = 0;
}
break;
case 3:
temp = ~(0x08 >> index);
index ++;
if(index == 4)
{
preStatus = 3;
status = 2;
index = 0;
}
break;
default:
status = 1;
index = 0;
break;
}
GPIOPinWrite(GPIO_PORTA_BASE, LEDs, temp<<2);
/* 取出temp各位,组成位字符串 */
bit4 = ((~temp)&0x08)>>3;
bit3 = ((~temp)&0x04)>>2;
bit2 = ((~temp)&0x02)>>1;
bit1 = ((~temp)&0x01)>>0;
sprintf(buffer, "%d%d%d%d/r/n/0", bit4, bit3, bit2, bit1);
/* 发送位字符串 */
UartPuts(buffer);
/* 使能定时器0 */
TimerEnable(TIMER0_BASE, TIMER_A);
}
相关文章推荐
- 基于LMS8962的跑马灯教学程序——定时器、串口及GPIO的使用
- BCB中使用API函数写简单串口程序(定时器接收)
- 二、ESP8266之GPIO 定时器 以及串口(基于LUA开发)
- 基于TX2440开发板在ADS1.2中编写LED的驱动(GPIO的使用)裸机程序
- U-Boot使用loadb下载程序(附测试代码) --基于Linux下Kermit工具
- 使用Win32创建串口通讯程序[转]
- 编写基于FormView的SDI串口程序
- Android程序中使用定时器Timer
- 神经网络与深度学习 使用Python实现基于梯度下降算法的神经网络和自制仿MNIST数据集的手写数字分类可视化程序 web版本
- 在MFC下使用OpenGL的一个简单的例子(基于单文档程序)
- 使用Spring 2.5 和 Hibernate 3.2 开发MVC Web程序(基于annotation特性)
- 使用串口模拟工具进行串口程序开发调试
- 基于ONVIF协议的(IPC)客户端程序开发-3:使用gSOAP生成Web Services框架代码
- MSP430学习笔记2-跑马灯程序,熟悉定时器寄存器的配置。
- stm32f407部分外设驱动,can总线,定时器,gpio,串口,系统时钟等
- 基于uClinux的开发应用程序-Helloworld和跑马灯程序
- 使用定时器实现简单的字体闪烁并实现字体跑马灯
- 基于s5pv210嵌入式linux使用其他动态、静态库文件程序的交叉编译
- 使用CXF开发WebService程序的总结(四):基于bean的客户端和服务端代码的编写
- 使用Win32创建串口通讯程序