第六届的试题还有些bug没有解决,所以先发出第七届的,还是和上次一样,暂时没有讲解。
main.c
#include "stm32f10x.h"
#include "led.h"
#include "lcd.h"
#include "eeprom.h"
#include "key.h"
#include "adc.h"
#include "usart.h"
#include "rtc.h"
static __INLINE uint32_t SysTick_Config1(uint32_t ticks);
void window_show(void);
u16 Adc_Val;//ADC的值
u8 receive=0,rx_index=0;//串口接收中断标志及接收数据量
u8 Rx_Buffer[30];//串口接收缓冲区
float k=0.1;//安全电压比例k
u8 print_time=0,led_blink=1;//上报标志位和led闪烁开启标志位
u8 show_mode=0;//显示模式 1为常规界面 2为设置界面
u8 first_print=1;//刷屏标志位
u8 led_blink_sta=1;//led闪烁标志位
extern u32 Time;//RTC时间计数值
extern __IO u8 LED_STATE;//LED的状态位
extern u8 set_select,set_hh,set_mm,set_ss;//设置界面的时间
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SysTick_Config1(SystemCoreClock/1000);
led_init();
key_init();
at24c02_init();
adc_init();
usart2_init();
rtc_init();
STM3210B_LCD_Init();
delay_ms(500);
LCD_Clear(White);
LCD_SetTextColor(Blue);
LCD_SetBackColor(White);
while(1)
{
window_show();
delay_ms(200);
}
}
void window_show(void)
{
u8 str[25],set_str[20];
u8 str1[25];
u8 hh,mm,ss;
Time=RTC_GetCounter();
hh=Time/3600;
mm=(Time%3600)/60;
ss=(Time%3600)%60;
if(first_print==1)
{
LCD_Clear(White);
first_print=0;
}
/*显示模式1:展示界面*/
if(show_mode==0)
{
//读取ADC的值
Adc_Val=adc_getval();
//从串口接收改变k值
if(receive==1)
{
usart2_senddata(Rx_Buffer);
if(Rx_Buffer[0]=='k')
{
k=0.1*(Rx_Buffer[3]-48);
usart2_senddata("OK\n");
}
receive=0;
}
//时间格式转换
sprintf(str1," %0.2d-%0.2d-%0.2d ",Time/3600,(Time%3600)/60,(Time%3600)%60);
//界面打印
sprintf(str," V1:%.2fV ",(float)Adc_Val/4096*3.3);
LCD_DisplayStringLine(Line1,str);
sprintf(str," k:%.1f ",k);
LCD_DisplayStringLine(Line2,str);
if(led_blink==0)//如果闪灯关闭
{
sprintf(str," LED:OFF ");
LCD_DisplayStringLine(Line3,str);
led_ctl(LED0,0);
}
else//如果闪灯开启
{
sprintf(str," LED:ON ");
LCD_DisplayStringLine(Line3,str);
if(((float)Adc_Val/4096*3.3)>(3.3*k))//如果ADC电压值大于基准电压 闪灯
{
led_blink_sta=!led_blink_sta;
led_ctl(LED0,led_blink_sta);
}
else
{
led_ctl(LED0,0);
}
}
sprintf(str," T:%0.2d-%0.2d-%0.2d",hh,mm,ss);
LCD_DisplayStringLine(Line4,str);
//定时上报
if(print_time==1)
{
sprintf(str,"%.2f+%.1f+%d\n",(float)Adc_Val/4096*3.3,k,Time);
usart2_senddata(str);
print_time=0;
}
}
/*显示模式1:设置界面*/
else
{
LCD_DisplayStringLine(Line1," Setting ");
sprintf(set_str," %0.2d-%0.2d-%0.2d ",set_hh,set_mm,set_ss);
LCD_DisplayStringLine(Line3,set_str);
}
}
static __INLINE uint32_t SysTick_Config1(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, 1); /* set Priority for Cortex-M0 System Interrupts */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
void USART2_IRQHandler(void)
{
u8 temp;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
/* Read one byte from the receive data register */
temp= USART_ReceiveData(USART2);
if(temp=='\n'||rx_index==30)
{
receive=1;
rx_index=0;
}
else
{
Rx_Buffer[rx_index++]=temp;
}
}
}
led.h
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#define LED_ALL GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15
#define LED0 0
#define LED1 1
#define LED2 2
#define LED3 3
#define LED4 4
#define LED5 5
#define LED6 6
#define LED7 7
void led_init(void);
void led_ctl(u8 led,u8 state);
void led_write(void);
#endif
led.c
#include "led.h"
__IO u8 LED_STATE=0xFF;
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
/* Configure PD0 and PD2 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = LED_ALL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
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_SetBits(GPIOC,LED_ALL);
led_write();
delay_ms(5);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
delay_ms(5);
}
void led_ctl(u8 led,u8 state)
{
if(state==1)
{
LED_STATE&=~(1<<(led));
led_write();
}
else
{
LED_STATE|=1<<(led);
led_write();
}
}
void led_write(void)
{
GPIO_WriteBit(GPIOC,GPIO_Pin_8,(LED_STATE>>0)&1);
GPIO_WriteBit(GPIOC,GPIO_Pin_9,(LED_STATE>>1)&1);
GPIO_WriteBit(GPIOC,GPIO_Pin_10,(LED_STATE>>2)&1);
GPIO_WriteBit(GPIOC,GPIO_Pin_11,(LED_STATE>>3)&1);
GPIO_WriteBit(GPIOC,GPIO_Pin_12,(LED_STATE>>4)&1);
GPIO_WriteBit(GPIOC,GPIO_Pin_13,(LED_STATE>>5)&1);
GPIO_WriteBit(GPIOC,GPIO_Pin_14,(LED_STATE>>6)&1);
GPIO_WriteBit(GPIOC,GPIO_Pin_15,(LED_STATE>>7)&1);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
key.h
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"
void key_init(void);
#endif
key.c
#include "key.h"
#include "usart.h"
extern u8 led_blink;
extern u8 show_mode,first_print;
extern u32 Print_Time;
u8 set_select=0,set_hh=0,set_mm=0,set_ss=0;
void key_init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, 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);
//PA0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//PA8
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource8);
EXTI_InitStructure.EXTI_Line = EXTI_Line8;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_Init(&NVIC_InitStructure);
//PB1
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_Init(&NVIC_InitStructure);
//PB2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource2);
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_Init(&NVIC_InitStructure);
}
//key1
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
led_blink=!led_blink;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
//key2
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line8) != RESET)
{
if(show_mode==0)
show_mode=1;
else
{
show_mode=0;
Print_Time=set_hh*3600+set_mm*60+set_ss;
}
first_print=1;
EXTI_ClearITPendingBit(EXTI_Line8);
}
}
//key3
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1) != RESET)
{
if(show_mode==1)
{
set_select=(set_select+1)%3;
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
}
//key4
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET)
{
if(show_mode==1)
{
switch(set_select)
{
case 0:
set_hh=(set_hh+1)%24;
break;
case 1:
set_mm=(set_mm+1)%24;
break;
case 2:
set_ss=(set_ss+1)%24;
break;
}
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
}
usart.h
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
void usart2_init(void);
void usart2_senddata(u8 *data);
#endif
usart.c
#include "usart.h"
void usart2_init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_AFIO, 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_Cmd(USART2, ENABLE);
}
void usart2_senddata(u8 *data)
{
int i=0;
do{
USART_SendData(USART2,data[i]);
while(!USART_GetFlagStatus(USART2,USART_FLAG_TXE));
i++;
}while(data[i]!=0);
}
adc.h
#ifndef __ADC_H
#define __ADC_H
#include "stm32f10x.h"
void adc_init(void);
u16 adc_getval(void);
#endif
adc.c
#include "adc.h"
void adc_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 = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
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_55Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
u16 adc_getval(void)
{
u16 adc_val;
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
adc_val = ADC_GetConversionValue(ADC1);
return adc_val;
}
rtc.h
#ifndef __RTC_H
#define __RTC_H
#include "stm32f10x.h"
void rtc_init(void);
#endif
rtc.c
#include "rtc.h"
u32 Time=23*3600+59*60+55;
u32 Print_Time=0*3600+0*60+0;
extern u8 print_time;
void rtc_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//RCC_ClocksTypeDef RCC_Clocks;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* 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();
/* 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 */
RTC_SetPrescaler(40000);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
// /* To output second signal on Tamper pin, the tamper functionality
// must be disabled (by default this functionality is disabled) */
// BKP_TamperPinCmd(DISABLE);
// /* Enable the RTC Second Output on Tamper Pin */
// BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);
RTC_SetCounter(Time);
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_SEC);
/* Toggle LED1 */
if(RTC_GetCounter()==86399)
{
RTC_SetCounter(0x0);
Time=0;
}
if(RTC_GetCounter()==Print_Time)
{
print_time=1;
}
/* Clear Interrupt pending bit */
}
}