1 >> 项目PID: 关于PID我没有什么可以说的,因为我是拿来就用,只调整 K_P ,K_I ,K_D 三个参数,实测效果可以.
2 >> Protothreads 使用的是 康奈尔大学ECE4760课程中的Protothreads (备注 gSysTick++; //1ms 所有的时间片 基于此)
修正了其中的一个bug:
这是原版的:
#ifdef MX250 #define PT_YIELD_TIME_msec(delay_time) \ do { static unsigned int time_thread ;\ time_thread = gSysTick + (delay_time) ; \ PT_YIELD_UNTIL(pt, (gSysTick >= time_thread)); \ } while(0); #endif
这是修正后的:
#if 1 #define PT_YIELD_TIME_msec(delay_time) \ do { static volatile unsigned int time_thread ;\ time_thread = gSysTick; \ PT_YIELD_UNTIL(pt, ((unsigned int)(gSysTick - time_thread) >= (unsigned int)(delay_time))); \ } while(0); #endif
3 >> 考虑到这个案子也没有什么没有太难的东西,而且这个只是第一次送样的代码(离产品还有一些距离),所以就当是对无私的热心地坛友的一声谢谢. (如果认识我们老板或者这个案子的客户,请保持沉默,别打我小报告)
4 >> 在 _isch 这个文件夹 里有原理图和需求文档 (备注:代码有些地方与文档并不一致)。项目通过编译 需要安装 SN-Link_Driver for Keil C51_V2.00.34。
5>> 这个案子并没有 按键 和 I2C,我把这两个文件也打包一起放上来,希望大家能用得上:
//app_key.c #include "app_cfg.h" #include "app_global.h" #include "app_timer.h" #ifdef UART1_EN #include "sn8f5702_uart.h" #endif #define KEY_GLOBALS #include "app_key.h" //#define DBG uart_printf code BYTE GpioKeyEvent[][5] = { //PDS(按键开始) SPR(短按松开) CPS(长按开始) CPH(长按保持) CPR(长按松开) {MSG_NONE, MSG_MODE, MSG_POWER_ON, KEY_POWER_LONG, KEY_POWER_LONG_BREAK}, //K1 {MSG_NONE, MSG_LIGHT, MSG_LIGHT_CPS, MSG_LIGHT_CPH, MSG_LIGHT_CPR }, //K2 }; TIMER idata gpioKeyWaitTimer; //TIMER gpioKeyScanTimer; GPIO_KEY_STATE idata GpioKeyState; void GpioKeyInit(void) { P_KEY_POWER_INPUT; GpioKeyState = GPIO_KEY_STATE_IDLE; //timer_set(&gpioKeyScanTimer, 0); } static u8_t GetGpioKeyIndex(void) { u8_t KeyIndex = 0xFF; if(P_KEY_POWER == 0) { KeyIndex = 0; } return KeyIndex; } KEY_EVENT GpioKeyScan(void) { static unsigned char idata PreKeyIndex = 0xFF; BYTE KeyIndex; KeyIndex = GetGpioKeyIndex(); switch(GpioKeyState) { case GPIO_KEY_STATE_IDLE: if(KeyIndex == 0xFF) { return MSG_NONE; } PreKeyIndex = KeyIndex; timer_set(&gpioKeyWaitTimer, GPIO_KEY_JTTER_TIME); //DBG(("GOTO JITTER!\n")); GpioKeyState = GPIO_KEY_STATE_JITTER; case GPIO_KEY_STATE_JITTER: if(PreKeyIndex != KeyIndex) { //DBG(("GOTO IDLE Because jitter!\n")); GpioKeyState = GPIO_KEY_STATE_IDLE; } else if(timer_expired(&gpioKeyWaitTimer)) { //DBG(("GOTO PRESS_DOWN!\n")); //P_KEY_OUT = 0; //Uart1_PutChar(0xA1); timer_set(&gpioKeyWaitTimer, GPIO_KEY_CP_TIME); GpioKeyState = GPIO_KEY_STATE_PRESS_DOWN; return GpioKeyEvent[PreKeyIndex][0];//PDS(按键开始) } break; case GPIO_KEY_STATE_PRESS_DOWN: if(PreKeyIndex != KeyIndex) { //DBG(("ADC KEY SP!*****\n")); //P_KEY_OUT = 1; //Uart1_PutChar(0xA2); GpioKeyState = GPIO_KEY_STATE_IDLE; return GpioKeyEvent[PreKeyIndex][1]; //SPR(短按松开) } else if(timer_expired(&gpioKeyWaitTimer)) { //DBG(("ADC KEY CP!********\n")); //P_KEY_OUT = 1; //Uart1_PutChar(0xA3); //P_LED_R_ON; timer_set(&gpioKeyWaitTimer, GPIO_KEY_CPH_TIME); GpioKeyState = GPIO_KEY_STATE_CP; return GpioKeyEvent[PreKeyIndex][2]; //CPS(长按开始) } break; case GPIO_KEY_STATE_CP: if(PreKeyIndex != KeyIndex) { //DBG(("ADC KEY CPR!*************\n")); //Uart1_PutChar(0xA4); //P_LED_R_OFF; GpioKeyState = GPIO_KEY_STATE_IDLE; return GpioKeyEvent[PreKeyIndex][4]; //CPR(长按松开) } else if(timer_expired(&gpioKeyWaitTimer)) { //DBG(("ADC KEY CPH!*************\n")); timer_set(&gpioKeyWaitTimer, GPIO_KEY_CPH_TIME); return GpioKeyEvent[PreKeyIndex][3]; // CPH(长按保持) } break; default: GpioKeyState = GPIO_KEY_STATE_IDLE; break; } return MSG_NONE; } //bsp_i2c.c #include "sn8f5702.h" #include "app_cfg.h" #include "app_global.h" #ifdef UART1_EN #include "sn8f5702_uart.h" #endif #include "bsp_i2c.h" #define I2C_Delay() _dly_1us(1) #define GET_ACK_TIME 250 /****************************************************************************************** *函数名称: void I2C_Idle(void) *入口参数: 无 *出口参数: 无 *函数功能: I2C总线空闲 ******************************************************************************************/ void I2C_Idle(void) { P_I2C_SCL_OUTPUT; P_I2C_SCL = 1; P_I2C_SDA_OUTPUT; P_I2C_SDA = 1; } /****************************************************************************************** *函数名称: void I2C_Start(void) *入口参数: 无 *出口参数: 无 *函数功能: I2C通信启始 SDA 1->0 while SCL High ******************************************************************************************/ void I2C_Start(void) { P_I2C_SCL_OUTPUT; P_I2C_SCL = 1; P_I2C_SDA_OUTPUT; P_I2C_SDA = 1; I2C_Delay(); P_I2C_SDA = 0; I2C_Delay(); P_I2C_SCL = 0; } /****************************************************************************************** *函数名称: void I2C_Stop(void) *入口参数: 无 *出口参数: 无 *函数功能: I2C通信结束 SDA 0->1 while SCL High ******************************************************************************************/ void I2C_Stop(void) { P_I2C_SCL_OUTPUT; P_I2C_SCL = 0; P_I2C_SDA_OUTPUT; P_I2C_SDA = 0; I2C_Delay(); P_I2C_SCL = 1; I2C_Delay(); P_I2C_SDA = 1; I2C_Delay(); } /** * @brief This function checks ACK/NACK from I2C slave. * @param None * @return None */ boolean I2C_ChkAck(void) { boolean Ack; unsigned char GetAckTime = GET_ACK_TIME; //返回ACK信号延时等待时间 P_I2C_SDA_INPUT; //Allow slave to send ACK P_I2C_SCL = 0; //slave send ACK P_I2C_SCL = 1; while(P_I2C_SDA && (--GetAckTime)); Ack = (!P_I2C_SDA); //Get ACK from slave P_I2C_SCL = 0; P_I2C_SDA_OUTPUT; // add by k.s return Ack; } /****************************************************************************************** *函数名称: boolean I2C_WriteByte(unsigned char SendByte) *入口参数: unsigned char SendByte--发送的字节 *出口参数: 无 *函数功能: 向I2C总线发送一个字节 *This function send one byte to I2C slave. ******************************************************************************************/ boolean I2C_WriteByte(unsigned char SendByte) { unsigned char i = 8; P_I2C_SDA_OUTPUT; P_I2C_SCL = 0; //设置I2C_SDA为输出 while(i--) //I2C_SDA脚从高位至低位发送数据 { if(SendByte & 0x80) /* MSB output first */ { P_I2C_SDA = 1; } else { P_I2C_SDA = 0; } SendByte <<= 1; P_I2C_SCL = 1; //拉高I2C_SCL I2C_Delay(); P_I2C_SCL = 0; //拉低I2C_SCL,以允许I2C_SDA脚w位数据发生变化 } return I2C_ChkAck(); } /****************************************************************************************** *函数名称: unsigned char I2C_ReadByte(void) *入口参数: 无 *出口参数: unsigned char RecByte--读取的字节 *函数功能: 向I2C总线读取一个字节 ******************************************************************************************/ void I2C_SendNoAck(void) { P_I2C_SDA = 1; P_I2C_SCL = 1; I2C_Delay(); P_I2C_SCL = 0; } unsigned char I2C_ReadByte(void) { unsigned char i = 8; unsigned char Dat = 0; P_I2C_SDA_INPUT; //设置I2C_SDA为输入 while(i--) { P_I2C_SCL = 1; //拉高I2C_SCL I2C_Delay(); Dat <<= 1; if(P_I2C_SDA) { Dat |= 0x01; } P_I2C_SCL = 0; //拉低I2C_SCL I2C_Delay(); } P_I2C_SDA_OUTPUT; //设置I2C_SDA为输出 return Dat; //返回数据 }
最新回复 [0]