我用的是EasyARM615,编译环境IAR,昨天我写了一段程序,程序的作用如下:系统默认初始显示值为30,用户根据自己的要求在一段时间内通过按下KEY2和KEY3来改变默认值,按下key2为加1,按下key3为减1,按后刷新显示屏,按下KEY4为设定完毕,此时,按下KEY2和KEY3不会改变设定值。可设定的范围在10到50之间,如果设定时间内无按键操作,显示值将衡定为为30。程序如下: #include "hw_types.h" #include "hw_memmap.h" #include "hw_gpio.h" #include "hw_ints.h" #include "sysctl.h" #include "I2CINT.H" #include "PCF8576.H" #include "LCD_TH3144.H" #include "hw_adc.h" #include "gpio.h" #include "adc.h" #include "debug.h"
#define KEY GPIO_PIN_4 #define KEY2 GPIO_PIN_5 #define KEY3 GPIO_PIN_5 #define KEY4 GPIO_PIN_4 void Go2Jtag(void)//防止jtag死锁 { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); GPIODirModeSet(GPIO_PORTD_BASE,KEY,GPIO_DIR_MODE_IN); if(GPIOPinRead(GPIO_PORTD_BASE,KEY)==0) { while(1); } }
void delay(unsigned int n) // 软件延迟函数 { volatile int i; for(;n>0;n--) { for(i=0;i<1000;i++); } }
int SetTemp=30;//设定初始显示值
void PlusOne(void) //设定显示值加1中断函数 { int SetTempH;//十位数 int SetTempL;//个位数 GPIOPinIntClear(GPIO_PORTD_BASE,KEY2);//清除中断 if(SetTemp>50)//如果设定显示值已经大于50,显示“错误” { Lcd_Seg.D1 = HexToSeg(0xe); } else { SetTemp++; SetTempH=SetTemp/10; SetTempL=SetTemp%10; Lcd_Seg.D1 = HexToSeg(SetTempH); Lcd_Seg.D2 = HexToSeg(SetTempL)+LCD_DP; Lcd_Seg.D3 = HexToSeg(0); Lcd_Seg.D4 = HexToSeg(0); } Lcd_Update();//到这里有问题了!!!!!!!!!!!!!!!问题见最后 } void SubOne(void) //设定初始值减1中断函数 { int SetTempH;//SetTemp的十位数 int SetTempL;//SetTemp个位数 GPIOPinIntClear(GPIO_PORTB_BASE,KEY3);//清除中断 if(SetTemp<10)//如果设定值已经小于10,显示“错误” { Lcd_Seg.D1 = HexToSeg(0xe); } else { SetTemp--; SetTempH=SetTemp/10; SetTempL=SetTemp%10; Lcd_Seg.D1 = HexToSeg(SetTempH); Lcd_Seg.D2 = HexToSeg(SetTempL)+LCD_DP; Lcd_Seg.D3 = HexToSeg(0); Lcd_Seg.D4 = HexToSeg(0); } Lcd_Update();();//到这里有问题了!!!!!!!!!!!!!!!问题见最后
}
void StopWatingForInt(void) //退出等待加减中断 { GPIOPinIntClear(GPIO_PORTA_BASE,KEY4);//清除中断 GPIOPinIntDisable(GPIO_PORTD_BASE,KEY2);//禁能中断 GPIOPinIntDisable(GPIO_PORTB_BASE,KEY3); }
int main(void) { I2CInit(100000, 1); if(PCF8576_Ini(MODE_E, NOGLITTER)!=1) // 初始化PCF8576驱动 { while(1); } Lcd_Seg.D1 = HexToSeg(3); //显示初值 Lcd_Seg.D2 = HexToSeg(0)+LCD_DP; Lcd_Seg.D3 = HexToSeg(0); Lcd_Seg.D4 = HexToSeg(0); Lcd_Update(); Go2Jtag(); SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_6MHZ); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIODirModeSet(GPIO_PORTD_BASE,KEY2,GPIO_DIR_MODE_IN); GPIODirModeSet(GPIO_PORTB_BASE,KEY3,GPIO_DIR_MODE_IN); GPIODirModeSet(GPIO_PORTA_BASE,KEY4,GPIO_DIR_MODE_IN); GPIOIntTypeSet(GPIO_PORTD_BASE,KEY2,GPIO_FALLING_EDGE); GPIOIntTypeSet(GPIO_PORTB_BASE,KEY3,GPIO_FALLING_EDGE); GPIOIntTypeSet(GPIO_PORTA_BASE,KEY4,GPIO_FALLING_EDGE); GPIOPortIntRegister(GPIO_PORTD_BASE,PlusOne);//注册中断处理程序函数 GPIOPortIntRegister(GPIO_PORTB_BASE,SubOne); GPIOPortIntRegister(GPIO_PORTA_BASE,StopWatingForInt); GPIOPinIntEnable(GPIO_PORTD_BASE,KEY2); GPIOPinIntEnable(GPIO_PORTB_BASE,KEY3); GPIOPinIntEnable(GPIO_PORTA_BASE,KEY4); delay(10000);//等待时间 } 可是当我按下key2后,程序执行到ISR(任何一个)的Lcd_Update()就走不下去了,我在调试的时候,发现这是由于在执行Lcd_Update()中的ISendByte(PCF8576, drive)函数即器件的选择与控制时出现了问题:似乎因控制PCF8576的数据一直都没有传送完成而停留在了while(I2C_state != STATE_IDLE)这一循环语句上。这是为什么阿?
|