一、題目
二、代碼
1.初始化函數
tx.c
#include "tx.h"
void LED_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0xff00;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIOD->ODR|=(1<<2);
GPIOC->ODR|=0xff00;
GPIOD->ODR&=~(1<<2);
}
void KEY_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
u8 key_status[4]={1,1,1,1};
u16 key_downtime[4]={0,0,0,0};
void KEY_Driver(void){
u8 i;
static u8 backup[4]={1,1,1,1};
static u16 timethr[4]={1000,1000,1000,1000};
for(i=0;i<4;i++){
if( backup[i]!=key_status[i]){
if(backup[i]!=0){
Key_action(i+1,0);
}
backup[i]=key_status[i];
}
if(key_downtime[i]>0){
if(key_downtime[i]>timethr[i]){
Key_action(i+1,1);
timethr[i]+=200;
}
}
else
timethr[i]=1000;
}
}
void KEY_Scan(void){
u8 i;
static u8 key_buf[4]={0xff,0xff,0xff,0xff};
key_buf[0]=(key_buf[0]<<1)|KEY1;
key_buf[1]=(key_buf[1]<<1)|KEY2;
key_buf[2]=(key_buf[2]<<1)|KEY3;
key_buf[3]=(key_buf[3]<<1)|KEY4;
for(i=0;i<4;i++){
if(key_buf[i]==0x00){
key_status[i]=0;
key_downtime[i]+=4;
}
else if(key_buf[i]==0xff){
key_status[i]=1;
key_downtime[i]=0;
}
}
}
void Tim4_Init(u16 arr,u16 psc){
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr-1;
TIM_TimeBaseStructure.TIM_Prescaler = psc-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM4, ENABLE);
}
//PA6 PWM輸出
void Tim3_Init(u32 fre,u8 en){
u32 arr;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
arr=1000000/fre;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr-1;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
if(en)
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
else
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
TIM_OCInitStructure.TIM_Pulse = (arr-1)*80/100;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM3, ENABLE);
}
tx.h
/*
程序說明: CT117E嵌入式競賽板LCD驅動程序
軟件環境: Keil uVision 4.10
硬件環境: CT117E嵌入式競賽板
日 期: 2011-8-9
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TX_H
#define __TX_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* LCD Registers */
#define KEY1 GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_0)
#define KEY2 GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_8)
#define KEY3 GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_1)
#define KEY4 GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_2)
void LED_Init(void);
void KEY_Init(void);
void KEY_Driver(void);
void KEY_Scan(void);
void Tim4_Init(u16 arr,u16 psc);
void Tim3_Init(u32 fre,u8 en);
extern void Key_action(int code,u8 sta);
#endif /* __TX_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
2.中斷函數
stm32f10x_it.c
extern u8 ms200_flag;
extern u8 ms500_flag;
extern u8 s1_flag;
void TIM4_IRQHandler(void)
{
static u16 ms200_count=0;
static u16 ms500_count=0;
static u16 s1_count=0;
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
KEY_Scan();
ms200_count++;
s1_count++;
if(ms200_count>=100){
ms200_count=0;
ms200_flag=1;
}
if(ms500_count>=250){
ms500_count=0;
ms500_flag=1;
}
if(s1_count>=500){
s1_count=0;
s1_flag=1;
}
}
}
3.主函數
main.c
#include "stm32f10x.h"
#include "lcd.h"
#include "i2c.h"
#include "tx.h"
#include "stdio.h"
u32 TimingDelay = 0;
u8 ms200_flag=1;
u8 ms500_flag=0;
u8 s1_flag=0;
u8 str[20];
u16 LED_MODE=0xffff;
u8 SAVE_flag=0;//0-位置1...
u8 Time_flag=0;//0-無,1-時,2-分,3-秒
u8 Status_flag=0;//0-Standby,1-Setting,2-Running,3-Pause
u16 time;
u8 hour=0,min=1,sec=55;
void Running_action(void);
void Key_action(int code,u8 sta);
void Write_action(void);
void Read_action(void);
void In_data(void);
void Show_Setdata(void);
void Show_time(void);
void Delay_Ms(u32 nTime);
//Main Body
int main(void)
{
SysTick_Config(SystemCoreClock/1000);
Delay_Ms(200);
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
i2c_init();
LED_Init();
KEY_Init();
Tim4_Init(2000,72);
Read_action();
while(1){
KEY_Driver();
if(ms200_flag){
ms200_flag=0;
Show_Setdata();
Running_action();
}
if(s1_flag){
s1_flag=0;
if(Status_flag==2){
time=hour*3600+min*60+sec;
time--;
if(time<=0)
time=0;
hour=time/3600;
min=time%3600/60;
sec=time%3600%60;
}
}
}
}
void Running_action(void){ //定時器運行 PWM輸出,LD1以1Hz頻率閃爍
if(Status_flag==2){
Tim3_Init(1000,1);
if(ms500_flag){
ms500_flag=0;
LED_MODE^=(1<<8);
GPIOC->ODR=LED_MODE;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
}
}
else {
Tim3_Init(1000,0);
LED_MODE|=(1<<8);
GPIOC->ODR=LED_MODE;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
}
}
void Key_action(int code,u8 sta){
if(code==1){
if(sta==0){ //key1短按
if(Status_flag!=1){
SAVE_flag++;
if(SAVE_flag>4)
SAVE_flag=0;
}
Read_action();
}
}
else if(code==2){
if(sta==0){
if(Status_flag==0){
Status_flag=1;
Time_flag=1;
}
else if(Status_flag==1){
Time_flag++;
if(Time_flag>3)
Time_flag=1;
}
}
else if(sta==1){ //key2長按,存儲
Write_action();
Time_flag=0;
Status_flag=0;
}
}
else if(code==3){
if(Status_flag==1){
In_data();
}
}
else if(code==4){
if(sta==0){
if(Status_flag!=2){
Status_flag=2;
Time_flag=0;
}
else if(Status_flag==2)
Status_flag=3;
else if(Status_flag==3)
Status_flag=2;
}
else if(sta==1){
Status_flag=0;
}
}
}
void Write_action(void){
if(SAVE_flag==0){
ic2_write(0x00,hour);Delay_Ms(5);
ic2_write(0x01,min);Delay_Ms(5);
ic2_write(0x02,sec);Delay_Ms(5);
}
else if(SAVE_flag==1){
ic2_write(0x03,hour);Delay_Ms(5);
ic2_write(0x04,min);Delay_Ms(5);
ic2_write(0x05,sec);Delay_Ms(5);
}
else if(SAVE_flag==2){
ic2_write(0x06,hour);Delay_Ms(5);
ic2_write(0x07,min);Delay_Ms(5);
ic2_write(0x08,sec);Delay_Ms(5);
}
else if(SAVE_flag==3){
ic2_write(0x09,hour);Delay_Ms(5);
ic2_write(0x0A,min);Delay_Ms(5);
ic2_write(0x0B,sec);Delay_Ms(5);
}
else if(SAVE_flag==4){
ic2_write(0x0C,hour);Delay_Ms(5);
ic2_write(0x0D,min);Delay_Ms(5);
ic2_write(0x0E,sec);Delay_Ms(5);
}
}
void Read_action(void){
if(SAVE_flag==0){
hour=i2c_read(0x00);Delay_Ms(5);
min=i2c_read(0x01);Delay_Ms(5);
sec=i2c_read(0x02);Delay_Ms(5);
}
else if(SAVE_flag==1){
hour=i2c_read(0x03);Delay_Ms(5);
min=i2c_read(0x04);Delay_Ms(5);
sec=i2c_read(0x05);Delay_Ms(5);
}
else if(SAVE_flag==2){
hour=i2c_read(0x06);Delay_Ms(5);
min=i2c_read(0x07);Delay_Ms(5);
sec=i2c_read(0x08);Delay_Ms(5);
}
else if(SAVE_flag==3){
hour=i2c_read(0x09);Delay_Ms(5);
min=i2c_read(0x0A);Delay_Ms(5);
sec=i2c_read(0x0B);Delay_Ms(5);
}
else if(SAVE_flag==4){
hour=i2c_read(0x0C);Delay_Ms(5);
min=i2c_read(0x0D);Delay_Ms(5);
sec=i2c_read(0x0E);Delay_Ms(5);
}
}
void In_data(void){
if(Time_flag==1){
hour++;
if(hour>23)
hour=0;
}
else if(Time_flag==2){
min++;
if(min>59)
min=0;
}
else if(Time_flag==3){
sec++;
if(sec>59)
sec=0;
}
}
void Show_Setdata(void){
sprintf((char*)str," No:%d ",SAVE_flag+1);
LCD_DisplayStringLine(Line2,str);
Show_time();
if(Status_flag==0)
sprintf((char*)str," Standby ");
else if(Status_flag==1)
sprintf((char*)str," Setting ");
else if(Status_flag==2)
sprintf((char*)str," Running ");
else if(Status_flag==3)
sprintf((char*)str," Pause ");
LCD_DisplayStringLine(Line6,str);
}
void Show_time(void){
if(Time_flag==0)
LCD_SetTextColor(White);
if(Time_flag==1)
LCD_SetTextColor(Green);
else
LCD_SetTextColor(White);
LCD_DisplayChar(Line4, 240, hour/10+'0');
LCD_DisplayChar(Line4, 225, hour%10+'0');
LCD_DisplayChar(Line4, 210, ':');
LCD_SetTextColor(White);
if(Time_flag==2)
LCD_SetTextColor(Green);
else
LCD_SetTextColor(White);
LCD_DisplayChar(Line4, 195, min/10+'0');
LCD_DisplayChar(Line4, 180, min%10+'0');
LCD_DisplayChar(Line4, 165, ':');
LCD_SetTextColor(White);
if(Time_flag==3)
LCD_SetTextColor(Green);
else
LCD_SetTextColor(White);
LCD_DisplayChar(Line4, 150, sec/10+'0');
LCD_DisplayChar(Line4, 135, sec%10+'0');
LCD_SetTextColor(White);
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}