一、题目
二、代码
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};
void KEY_Driver(void){
u8 i;
static u8 backup[4]={1,1,1,1};
for(i=0;i<4;i++){
if(backup[i]!=key_status[i]){
if(backup[i]!=0)
Key_action(i+1);
backup[i]=key_status[i];
}
}
}
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;
}
else if(key_buf[i]==0xff){
key_status[i]=1;
}
}
}
void Adc1_Init(void){
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
u16 Get_adc(void){
u16 temp;
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==0);
temp=ADC_GetConversionValue(ADC1);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
return temp;
}
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);
TIM_Cmd(TIM4, 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 --------------------------------------------------------*/
#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)
extern void Key_action(int code);
void LED_Init(void);
void KEY_Init(void);
void KEY_Driver(void);
void KEY_Scan(void);
void Adc1_Init(void);
u16 Get_adc(void);
void Tim4_Init(u16 arr,u16 psc);
#endif /* __TX_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
i2c.c中
void i2c_write(u16 add,u8 data){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}
u8 i2c_read(u16 add){
u8 temp;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(add);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
temp=I2CReceiveByte();
I2CSendAck();
I2CStop();
return temp;
}
2.中断函数
stm32f10x_it.h
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++;
ms500_count++;
s1_count++;
if(ms200_count>=100){
ms200_count=0;
ms200_flag=1;
}
if(ms500_count>=100){
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 "tx.h"
#include "i2c.h"
#include "stdio.h"
u32 TimingDelay = 0;
u8 ms200_flag=1;
u8 ms500_flag=0;
u8 s1_flag=0;
u8 SET_flag=0;//0-数据显示界面,1-设置界面
u8 Index_flag=0;//参数选择
u8 Status_flag=0;//0-Upper,1-Lower,2-Normal
float adc_value;//实时电压
float adc_min=1.2;//最小电压
float adc_max=2.4;//最大电压
u8 Led_flag=0; //0-上限提示灯为LD1,下限为LD2,1-上限LD2,下限LD1
u8 Led1_flag=0;//LD1标志
u8 Led2_flag=0;//LD2标志
u16 LED_MODE=0xffff;
u8 str[20];
void Delay_Ms(u32 nTime);
void Refresh(void);
void Key_action(int code);
void Show_real(void);
void Show_set(void);
//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();
Adc1_Init();
Tim4_Init(2000,72);
adc_max=i2c_read(0x00)*1.0/10;Delay_Ms(5);
adc_min=i2c_read(0x01)*1.0/10;Delay_Ms(5);
Led_flag=i2c_read(0x02);Delay_Ms(5);
while(1){
KEY_Driver();
if(ms200_flag){
ms200_flag=0;
Refresh();
if(SET_flag==0)
Show_real();
else if(SET_flag==1)
Show_set();
}
}
}
void Refresh(void){
adc_value=Get_adc()*3.3/4096;
if(adc_value>=adc_max)
Status_flag=0; //上限
else if(adc_value<=adc_min)
Status_flag=2; //下限
else
Status_flag=1;
if(Status_flag==0){ //上限
if(Led_flag==0){
Led1_flag=1;
Led2_flag=0;
}
else if(Led_flag==1){
Led1_flag=0;
Led2_flag=1;
}
}
if(Status_flag==1){ //正常
Led1_flag=0;
Led2_flag=0;
}
if(Status_flag==2){ //下限
if(Led_flag==0){
Led1_flag=0;
Led2_flag=1;
}
else if(Led_flag==1){
Led1_flag=1;
Led2_flag=0;
}
}
if(Led1_flag)
LED_MODE^=(1<<8);
else
LED_MODE|=(1<<8);
GPIOC->ODR=LED_MODE;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
if(Led2_flag)
LED_MODE^=(1<<9);
else
LED_MODE|=(1<<9);
GPIOC->ODR=LED_MODE;
GPIOD->ODR|=(1<<2);
GPIOD->ODR&=~(1<<2);
}
void Key_action(int code){
if(code==1){
SET_flag^=1;
if(SET_flag==0){
i2c_write(0x00,adc_max*10);Delay_Ms(5);
i2c_write(0x01,adc_min*10);Delay_Ms(5);
i2c_write(0x02,Led_flag);Delay_Ms(5);
}
}
else if(code==2){
if(SET_flag==1){
Index_flag++;
if(Index_flag>3)
Index_flag=0;
}
}
else if(code==3){
if(SET_flag==1){
if(Index_flag==0) {
adc_max+=0.3;
if(adc_max>=3.3)
adc_max=3.3;
}
else if(Index_flag==1) {
adc_min+=0.3;
if(adc_min>=3.3)
adc_min=3.3;
}
else if(Index_flag==2){
Led_flag=1;
}
else if(Index_flag==3){
Led_flag=0;
}
}
}
else if(code==4){
if(SET_flag==1){
if(Index_flag==0) {
adc_max-=0.3;
if(adc_max<=0.0)
adc_max=0.0;
}
else if(Index_flag==1) {
adc_min-=0.3;
if(adc_min<=0.0)
adc_min=0.0;
}
else if(Index_flag==2){
Led_flag=0;
}
else if(Index_flag==3){
Led_flag=1;
}
}
}
}
void Show_real(void){
sprintf((char*)str," Main ");
LCD_DisplayStringLine(Line1, str);
sprintf((char*)str," ");
LCD_DisplayStringLine(Line3, str);
sprintf((char*)str," Volt: %.2fV ",adc_value);
LCD_DisplayStringLine(Line5, str);
switch(Status_flag){
case 0:
sprintf((char*)str," Status: Upper ");
break;
case 1:
sprintf((char*)str," Status: Normal ");
break;
case 2:
sprintf((char*)str," Status: Lower ");
break;
default:
break;
}
LCD_DisplayStringLine(Line7, str);
sprintf((char*)str," ");
LCD_DisplayStringLine(Line9, str);
}
void Show_set(void){
sprintf((char*)str," Setting ");
LCD_DisplayStringLine(Line1, str);
if(Index_flag==0)
LCD_SetTextColor(Green);
else
LCD_SetTextColor(White);
sprintf((char*)str," Max Volt: %.1fV ",adc_max);
LCD_DisplayStringLine(Line3, str);
LCD_SetTextColor(White);
if(Index_flag==1)
LCD_SetTextColor(Green);
else
LCD_SetTextColor(White);
sprintf((char*)str," Min Volt: %.1fV ",adc_min);
LCD_DisplayStringLine(Line5, str);
LCD_SetTextColor(White);
if(Index_flag==2)
LCD_SetTextColor(Green);
else
LCD_SetTextColor(White);
if(Led_flag==0)
sprintf((char*)str," Upper: LD1 ");
else
sprintf((char*)str," Upper: LD2 ");
LCD_DisplayStringLine(Line7, str);
LCD_SetTextColor(White);
if(Index_flag==3)
LCD_SetTextColor(Green);
else
LCD_SetTextColor(White);
if(Led_flag==0)
sprintf((char*)str," Lower: LD2 ");
else
sprintf((char*)str," Lower: LD1 ");
LCD_DisplayStringLine(Line9, str);
LCD_SetTextColor(White);
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}