蓝桥练习
//io.c
#include "IO.h"
///LED
///初始化
void LED_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC,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 = LEDAll;
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);
}
///led控制
void led_contol(u16 ledx,u8 state)
{
if(state==1)
{
GPIO_ResetBits(GPIOC,ledx);
GPIOD->ODR|=(1<<2);
GPIOD->ODR &=~(1<<2);
}
else if(state==0)
{
GPIO_SetBits(GPIOC,ledx);
GPIOD->ODR|=(1<<2);
GPIOD->ODR &=~(1<<2);
}
}
key///
/初始化//
void key_init()
{
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_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
///按键扫描
u8 key_scan(void)//要用u8,不要用void,因为void不能有返回值
{
static u8 key_down=1;//按下按键标志位为1
if(key_down&&(B1==0||B2==0||B3==0||B4==0))
{
Delay_Ms(5);
key_down=0;
if(B1==0) return 1;
else if(B2==0) return 2;
else if(B3==0) return 3;
else if(B4==0) return 4;
}
else if (key_down==0&&B1==1&&B2==1&&B3==1&&B4==1)
key_down=1;
return 0;
}
//按键读取只能短按
//要实现的功能如下
//B1:在主页面实现Led1的开关(开的时候要求闪烁)
//B2:切换主页面和设置页面
//B3:在设置页面高亮选择时分秒
//B4:高亮的时分秒可以进行调整
//标志位很重要,可以每种状态用一个标志位然后在另几个函数通过转换标志位来实现功能
//B1:
u8 led_noise_flag=0;//指示灯
//B2:
u8 page_flag=0;//翻页,0为主页面,1为设置页面
//B3:
u8 time_flag=0;//选择要修改的时间标志位
//B4:
u8 send_hh=0;
u8 send_mm=0;
u8 send_ss=0;
void key_read(void)
{
static u8 key_val=0;
key_val=key_scan();//一定要把函数的返回值给一个变量
switch (key_val)
{
case 1:
{
if(page_flag==0)
{
led_noise_flag^=1;//打开或是关闭指示灯
}
}break;
case 2:
{
if(page_flag==0)//如果在主页面按下b2键
{
page_flag=1;//进入设置页面
LCD_ClearLine( Line2);//主页面内容清空
LCD_ClearLine( Line3);//
LCD_ClearLine( Line4);//
LCD_ClearLine( Line5);//
LCD_ClearLine( Line6);//
}
else if(page_flag==1)//如果在设置界面按下b2
{
page_flag=0;//切回主页面
time_flag=0;//取消高亮
}
}break;
case 3:
{
if(page_flag==1)
{
time_flag++;
if(time_flag>3)
{
time_flag=1;
}
}
}break;
case 4:
{
if(time_flag==1)
{
send_hh++;
if (send_hh>23)
send_hh=0;
}
if(time_flag==2)
{
send_mm++;
if (send_mm>59)
send_mm=0;
}
if(time_flag==3)
{
send_ss++;
if (send_ss>59)
send_ss=0;
}
将修改后的时分秒写入EEPROM
x24_write(0x10,send_hh);
Delay_Ms(5);
x24_write(0x20,send_mm);
Delay_Ms(5);
x24_write(0x30,send_ss);
Delay_Ms(5);
}break;
}
}
//按键读取支持长短按
//void key_read(void)
//{
// static u16 key1_sum=0;
// if(B1==0)
// {
// key1_sum++;
// if (key1_sum ==1)
// {
// GPIOD->ODR|=(1<<2);
// GPIOC->ODR^=(1<<12);
// GPIOD->ODR &=~(1<<2);
//
// }
//
// }
//else
//{
// key1_sum=0;
//}
//}
/ADC数模转换ADC1
void adc_init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
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_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
Get_ADC and VOLT///
u16 adc_get(void)
{
u16 temp=0;
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//启动adc1开始转换
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==0)
temp=ADC_GetConversionValue(ADC1);
ADC_SoftwareStartConvCmd(ADC1,DISABLE);//关闭adc1开始转换
return temp;
}
float volt_get()///用float是因为电压值可能为小数
{
float V;//电压
V=(float)adc_get()*3.3/4095;
return V;
}
/串口
void usart_init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
// USART_ITConfig(USART2, USART_IT_TXE, ENABLE);这个不要写
USART_Cmd(USART2, ENABLE);
}
//串口中断///与接收有关
u8 rx_chuchun[20];
u8 rxover=0;
u8 rx_jishu=0;
void USART2_IRQHandler(void)
{
u8 temp;//将接收到的数据放在一个变量中
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//判断是否接收数据和中断
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清除标志位
temp=USART_ReceiveData(USART2);//将接收到的数据放在变量里
//然后判断数据是否接收完了
if(temp=='\n')//接收数据以‘/n'为结尾,标志接收完毕
{
rx_jishu=0;//接受计数值清零
rxover=0;//接受完成标志位置1
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
}else
{
rx_chuchun[rx_jishu]=temp;
rx_jishu++;
}
}
}
//串口发送
void usart_send(u8 *str)//传入参数为一个指针,将传入的数据逐个发送出去直到传送完毕
{
u8 zhizhen=0;
do
{
USART_SendData(USART2,str[zhizhen]);//发送数据
zhizhen++;
while (USART_GetFlagStatus(USART2,USART_FLAG_TXE)==0);
} while(str[zhizhen]!=0);
}
/串口功能实现
u8 i;
u8 str[20];
float k=0.1;
void usart_show()
{
u32 times;
u8 HH1;
u8 MM1;
u8 SS1;
float volt;
for (i=0;i<20;i++)//清空数组
{
str[i]=0;
}
if(rxover)//如果接收到了
{
if(rx_chuchun[0]=='k')
{
sprintf((char*)str,"ok\n");
usart_send(str);
}
sprintf((char*)str,"%c ",rx_chuchun[3]);//%c是以字符形式输出,只输出一个字符,因为只有第四个数在变所以
x24_write(0x70,rx_chuchun[0]);
for (i=0;i<20;i++)//清空数组
{
rx_chuchun[i]=0;
}
rxover=0;//接受完成标志位置1
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}
volt=volt_get();
times=RTC_GetCounter();
HH1=times/3600;
MM1=times%3600/60;
SS1=times%3600%60;
if(times==(send_hh*3600+send_mm*60+send_ss))
{
sprintf((char*)str,"%.2f+%.1f+%.2d%.2d%.2d\n",volt,k,HH1,MM1,SS1);
usart_send(str);
for (i=0;i<20;i++)//清空数组
{
str[i]=0;
}
}
}
///RTC///
u32 time=23*3600+59*60+55;
void rtc_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;//如果不写中断就无法进入中断服务函数,就无法清零
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_SetPrescaler(40000);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
RTC_SetCounter(time);
RTC_WaitForLastTask();
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
}
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
if(RTC_GetCounter()==86400-1)//添上这个语句其他的复制粘贴
{
RTC_SetCounter(0x0);
}
/* Clear Interrupt pending bit */
RTC_ClearITPendingBit(RTC_FLAG_SEC);
}
}
///函数功能:10kHz,3/7方波
void timer_init(u16 psc,u16 arr)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定时功能
TIM_OCInitTypeDef TIM_OCInitStructure;//输出通道
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Prescaler =psc;//分频系数pec=72
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseStructure.TIM_Period = arr;//计数周期1000,arr每一加1,就通过1M/1000波形
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
输出用OC,输入捕获用IC,中断服务函数里用TIM_IT_CC1,输出比较用OC,中断服务函数中用TIM_IT_CC2和TIM_IT_CC3,要用两个中断服务函数
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 30;//占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig( TIM3, TIM_IT_Update, ENABLE);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
}
void TIM3_IRQHandler(void)
{
if( TIM_GetITStatus( TIM3, TIM_IT_CC2))//如果TIM捕获比较2个中断源的中断发生
{
TIM_ClearITPendingBit( TIM3, TIM_IT_CC2);//清除中断挂起位
}
}
//iIC
void x24_write(u8 adress,u8 data)//写入EEPROM
{
I2CStart();//开始
I2CSendByte(0xa0);//
I2CWaitAck();
I2CSendByte(adress);//
I2CWaitAck();
I2CSendByte(data);//
I2CWaitAck();
I2CStop();
}
u8 x24_read(u8 adress)//读取EEPROM
{
u8 temp;
I2CStart();//开始
I2CSendByte(0xa0);//
I2CWaitAck();
I2CSendByte(adress);//
I2CWaitAck();
I2CStart();//开始
I2CSendByte(0xa1);//
I2CWaitAck();
temp=I2CReceiveByte();//将接收到的东西存入一个变量
I2CWaitAck();
I2CStop();//停止
return temp;//返回变量值
}
display.c
#include "display.h"
#include "stdio.h"
#include "io.h"
#include "function.h"
#include "lcd.h"
u8 string[20];
extern float k;
extern u8 page_flag;
extern u8 time_flag;
extern u8 send_HH;
extern u8 send_MM;
extern u8 send_SS;
extern u8 led_noise_flag;//指示灯报警;
void Display_page(void)
{
if(page_flag==0)//显示主页面
{
u32 time;
u8 HH;
u8 MM;
u8 SS;
float volt;
// u8 xiaoshu;
// float shu;
volt = Get_volt();
sprintf((char*)string," V1:%.2f ",volt);
LCD_DisplayStringLine(Line2,string);
k=(float)(_24c02_read(0x70)-48)/10;
// k =(float) (gewei+xiaoshu)/10;
// k = (float)xiaoshu-48;
sprintf((char*)string," k:%.1f ",k);
LCD_DisplayStringLine(Line3,string);
if(led_noise_flag==1)
{
LCD_DisplayStringLine(Line4," LED:ON ");
}
else if(led_noise_flag==0)
{
LCD_DisplayStringLine(Line4," LED:OFF ");
}
time = RTC_GetCounter();
HH = time/3600;
MM = time%3600/60;
SS = time%3600%60;
sprintf((char*)string," T:%.2d:%.2d:%.2d ",HH,MM,SS);
LCD_DisplayStringLine(Line5,string);
}
if(page_flag==1)
{
LCD_DisplayStringLine(Line2," Setting ");
if(time_flag==0)
{
LCD_DisplayChar(Line4,216,send_HH/10+48);//加48和加'0'效果一样,都是因为ASCILL码
LCD_DisplayChar(Line4,200,send_HH%10+48);
LCD_DisplayChar(Line4,182,':');
LCD_DisplayChar(Line4,166,send_MM/10+'0');//因为一个数占16位所以每隔16写一个
LCD_DisplayChar(Line4,150,send_MM%10+'0');
LCD_DisplayChar(Line4,135,':');
LCD_DisplayChar(Line4,116,send_SS/10+'0');
LCD_DisplayChar(Line4,100,send_SS%10+'0');
}
if(time_flag==1)
{
LCD_SetTextColor(Red);
LCD_DisplayChar(Line4,216,send_HH/10+'0');
LCD_DisplayChar(Line4,200,send_HH%10+'0');
LCD_SetTextColor(White);
LCD_DisplayChar(Line4,166,send_MM/10+'0');
LCD_DisplayChar(Line4,150,send_MM%10+'0');
LCD_DisplayChar(Line4,116,send_SS/10+'0');
LCD_DisplayChar(Line4,100,send_SS%10+'0');
}
if(time_flag==2)
{
LCD_DisplayChar(Line4,216,send_HH/10+'0');
LCD_DisplayChar(Line4,200,send_HH%10+'0');
LCD_SetTextColor(Red);
LCD_DisplayChar(Line4,166,send_MM/10+'0');
LCD_DisplayChar(Line4,150,send_MM%10+'0');
LCD_SetTextColor(White);
LCD_DisplayChar(Line4,116,send_SS/10+'0');
LCD_DisplayChar(Line4,100,send_SS%10+'0');
}
if(time_flag==3)
{
LCD_DisplayChar(Line4,216,send_HH/10+'0');
LCD_DisplayChar(Line4,200,send_HH%10+'0');
LCD_DisplayChar(Line4,166,send_MM/10+'0');
LCD_DisplayChar(Line4,150,send_MM%10+'0');
LCD_SetTextColor(Red);
LCD_DisplayChar(Line4,116,send_SS/10+'0');
LCD_DisplayChar(Line4,100,send_SS%10+'0');
LCD_SetTextColor(White);
}
}
}