1 >> 项目PID参考了以下帖子: 关于PID我没有什么可以说的,因为我是拿来就用,只调整 K_P ,K_I ,K_D 三个参数,实测效果可以.
https://www.amobbs.com/thread-5556400-1-1.html
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 这个文件夹 里有原理图和需求文档 (备注:代码有些地方与文档并不一致)
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!
"));
GpioKeyState = GPIO_KEY_STATE_JITTER;
case GPIO_KEY_STATE_JITTER:
if(PreKeyIndex != KeyIndex)
{
//DBG(("GOTO IDLE Because jitter!
"));
GpioKeyState = GPIO_KEY_STATE_IDLE;
}
else if(timer_expired(&gpioKeyWaitTimer))
{
//DBG(("GOTO PRESS_DOWN!
"));
//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!*****
"));
//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!********
"));
//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!*************
"));
//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!*************
"));
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; //返回数据
}
好资料,谢谢分亨
可以把timer_set和timer_expired函数贴出来一下吗,学习一下实现的思路
一周热门 更多>