//LCD初始化
void LCD_Init(void)
{
int i;
GPIOPinWrite(AIO,0x30); //GPIOA口出0x30
GPIOPinWrite(RS,0) ; //RS0
GPIOPinWrite(RW,0) ; //RW0
for(i=0;i<3;i++)
{
GPIOPinWrite(E,0x01<<2) ; //E1
GPIOPinWrite(E,0) ; //E=0
Delay(500* (TheSysClock / 4000000)); // 延时约500us
}
}
//LCD命令写
void Write_Com(uchar a)
{
GPIOPinTypeOut(AIO); //GPIOA为输出
GPIOPinWrite(RS,0) ; //RS=0
GPIOPinWrite(RW,0x01<<1) ; //RW=1
GPIOPinWrite(E,0x01<<2) ; //E=1
GPIOPinTypeIn(AIO); //GPIOA为输入
while (0x80==(GPIOPinRead(AIO)&0x80)) //测试忙闲
;
GPIOPinWrite(E,0) ; //E=0
GPIOPinWrite(RW,0) ; //RW=0
GPIOPinTypeOut(AIO); //GPIOA为输出
GPIOPinWrite(AIO,a); //GPIOA口出a
GPIOPinWrite(E,0x01<<2) ; //E=1
GPIOPinWrite(E,0) ; //E=0
}
//LCD数据写
void Write_Data(uchar a)
{
GPIOPinTypeOut(AIO); //GPIOA为输出
GPIOPinWrite(RS,0) ; //RS=0
GPIOPinWrite(RW,0x01<<1) ; //RW=1
GPIOPinWrite(E,0x01<<2) ; //E=1
GPIOPinTypeIn(AIO); //GPIOA为输入
while (0x80==(GPIOPinRead(AIO)&0x80)) //测试忙闲
;
GPIOPinWrite(E,0) ; //E=0
GPIOPinWrite(RS,1) ; //RS=1
GPIOPinWrite(RW,0) ; //RW=0
GPIOPinTypeOut(AIO); //GPIO A为输出
GPIOPinWrite(AIO,a); //GPIO A口出a
GPIOPinWrite(E,0x01<<2) ; //E=1
GPIOPinWrite(E,0) ; //E=0
}
// 系统初始化
void SystemInit(void)
{
SysCtlLDOSet(SYSCTL_LDO_2_50V); // 设置LDO输出电压
SysCtlClockSet(SYSCTL_USE_OSC | // 系统时钟设置,采用主振荡器
SYSCTL_OSC_MAIN |
SYSCTL_XTAL_6MHZ |
SYSCTL_SYSDIV_1);
TheSysClock = SysCtlClockGet(); // 获取系统时钟,单位:Hz
}
// 计算并显示时间
void Timer_Disp( void )
{
unsigned int a,b,f;
// 计算并显示小时
a=(sjjs/3600);
b=a%10;
a=a/10;
Write_Com(0xc4); //小时十位
Write_Data(0X30+a);
Write_Data(0X30+b);
Write_Data(0x3a);
// 计算并显示分钟
f=sjjs%3600;
a=f/60;
b=a%10;
a=a/10;
Write_Data(0X30+a);
Write_Data(0X30+b);
Write_Data(0x3a);
// 计算并显示秒
f=sjjs%60;
b=f%10;
a=f/10;
Write_Data(0X30+a);
Write_Data(0X30+b);
}
// 主函数(程序入口)
int main(void)
{
SystemInit(); // 系统初始化
uint c;
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0); //使能定时器模块
TimerConfigure(TIMER0_BASE , TIMER_CFG_32_BIT_PER); //配置定时器为32位周期定时器
TimerLoadSet(TIMER0_BASE , TIMER_A , 3000000UL); //设置定时器初值(0.5S)
TimerIntEnable(TIMER0_BASE , TIMER_TIMA_TIMEOUT); //使能定时器超时中断
IntEnable(INT_TIMER0A); //使能定时器中断
IntMasterEnable(); //使能处理器中断
TimerEnable(TIMER0_BASE , TIMER_A); //使能定时器计数
SysCtlPeriEnable(SYSCTL_PERIPH_GPIOA); //使能GPIOA口外设
GPIOPinTypeOut(GPIO_PORTA_BASE ,0xFF); //GPIOA为输出
SysCtlPeriEnable(SYSCTL_PERIPH_GPIOF); //使能GPIOF口外设
GPIOPinTypeOut(GPIO_PORTF_BASE ,0x07); //PF0,1,2为输出
GPIOPinTypeIn(GPIO_PORTF_BASE ,0xC0); //PF6,7为输入
LCD_Init(); //LCD初始化
Write_Com(0x38); //设置工作方式
Write_Com(0x01); //清除显示
Write_Com(0x06); //设置输入方式
Write_Com(0x0c); //设置显示方式
Write_Com(0x82);
Write_Data(0x45); //显示Easy ARM1138
Write_Data(0x61);
Write_Data(0x73);
Write_Data(0x79);
Write_Data(0x20);
Write_Data(0x41);
Write_Data(0x52);
Write_Data(0x4d);
Write_Data(0x31);
Write_Data(0x31);
Write_Data(0x33);
Write_Data(0x38);
Timer_Disp(); //显示时间
while(1)
{
if(GPIOPinRead(sw1)==0)
{
Delay(50* (TheSysClock / 4000)); //消抖,延时约50ms
if(GPIOPinRead(sw1)==0)
{ //选择键按下
for(;;)
{
if(sz==0x08)
{ //原为小时十位闪烁
sz=0x04; //改为小时个位闪烁
SJ=0;
for(;;)
if(GPIOPinRead(sw1)) //选择键松开
goto loop;
}
if(sz==0x04)
{ //原为小时个位闪烁
sz=0x02; //改为分钟十位闪烁
SJ=0;
for(;;)
if(GPIOPinRead(sw1)) //选择键松开
goto loop;
}
if(sz==0x02)
{ //原为分钟十位闪烁
sz=0x01; //改为分钟个位闪烁
SJ=0;
for(;;)
if(GPIOPinRead(sw1)) //选择键松开
goto loop;
}
{ //原无闪烁或为分钟个位闪烁
sz=0x08; //改为小时十位闪烁
SJ=0;
for(;;)
if(GPIOPinRead(sw1)) //选择键松开
goto loop;
}
}
}
}
loop:if(GPIOPinRead(sw2)==0)
{ //+1键按下
Delay(50* (TheSysClock / 4000)); //消抖,延时约50ms
if(GPIOPinRead(sw2)==0)
{
for(;;)
{
if(sz==0x08)
{ //小时十位闪烁
if(sjjs/36000<2)
sjjs+=36000 ; //小时十位+1
else
sjjs%=36000;
SJ=0;
for(;;)
if(GPIOPinRead(sw2)) //+1键松开
goto loop;
}
if(sz==0x04)
{ //小时个位闪烁
c=sjjs%36000;
if(c/3600<9)
sjjs+=3600 ; //小时个位+1
else
sjjs-=3600*9;
SJ=0;
for(;;)
if(GPIOPinRead(sw2)) //+1键松开
goto loop;
}
if(sz==0x02)
{ //分钟十位闪烁
c=sjjs%36000;
c%=3600;
if(c/600<5)
sjjs=sjjs+600; //分钟十位+1
else
sjjs-=600*5;
SJ=0;
for(;;)
if(GPIOPinRead(sw2)) //+1键松开
goto loop;
}
if(sz==0x01)
{ //分钟个位闪烁
c=sjjs%36000;
c%=3600;
c=c%600;
if(c/60<9)
sjjs+=60 ; //分钟个位+1
else
sjjs-=60*9;
SJ=0;
for(;;)
if(GPIOPinRead(sw2)) //+1键松开
goto loop;
}
}
}
}
}
}
// 定时器的中断服务函数
void Timer0A_ISR(void)
{
unsigned long ulStatus;
ulStatus = TimerIntStatus(TIMER0_BASE , true); //读取中断状态
TimerIntClear(TIMER0_BASE , ulStatus); //清除中断状态,重要!
if ( ulStatus & TIMER_TIMA_TIMEOUT ) //如果是定时器超时中断
{
zdjs+=1;
if(zdjs&0x01)
{ //0.5秒
if(sz)
{
switch(sz)
{
case 1:Write_Com(0xc8);Write_Data(0x20);break; //分钟个位灭
case 2:Write_Com(0xc7);Write_Data(0x20);break; //分钟十位灭
case 4:Write_Com(0xc5);Write_Data(0x20);break; //小时个位灭
case 8:Write_Com(0xc4);Write_Data(0x20);break; //小时十位灭
}
}
}
else
{ //一秒
sjjs+=1;
if(sjjs>23*3600+59*60+59)
sjjs=0;
Timer_Disp(); // 显示时间
SJ+=1;
if(sz)
{
if(SJ>29)
{
sz=0; //停止闪烁
}
}
}
}
}
本人使用的是IAR EWARM(IAR Embedded Workbench for ARM)集成开发环境,利用周立功公司提供的工程模板,输入以上的源程序,点击菜单“Project”→“Mark”进行编译,或按F7键,根据提示修改错误,再进行编译直至无错误为止 。
3 软件调试
编译无误后即可点击菜单“Project”→“Dbuge”下载源程序的机器码至开发板(或按Ctrl+D),同时在桌面上出现了几个调试用的快捷按钮——运行(go)、运行到光标处(Run to Cursor)、步出(Step Out)、步入(Step Into)、步越(Step Over)、停止(Break)、复位(Reset)等。通过选择上述不同的快捷按钮,以及观察变量的值(点击菜单“View”→“Watch”在Expression中输入变量名,即可在Value中看到该变量的值;或将光标悬停在某变量上,即可看到该变量的值),来调试程序,直至一切无误后即可全速运行了(点击快捷按钮go)。 |