本程序采用STM32F103C8T6,flash模拟EEPROM,使用外部中断,以按键触发可以将此时的3个通道的adc数据保存到flash中,掉电保存不丢失数据。
程序如下:
adc.h文件
#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
void Adc_Init(void);
u16 Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);
int get_adc(u8 dex);
#endif
adc.c文件
#include "adc.h"
#include "delay.h"
extern int adcr,adcg,adcb;
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_Init(GPIOA,&GPIO_InitStructure);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
ADC_InitStructure.ADC_NbrOfChannel=1;
ADC_InitStructure.ADC_ScanConvMode=DISABLE;
ADC_Init(ADC1,&ADC_InitStructure);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
u16 Get_Adc(u8 ch)
{
ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_1Cycles5);
ADC_RegularChannelConfig(ADC1,ch,2,ADC_SampleTime_1Cycles5);
ADC_RegularChannelConfig(ADC1,ch,3,ADC_SampleTime_1Cycles5);
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
return ADC_GetConversionValue(ADC1);
}
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}
int get_adc(u8 dex)
{
int over;
while(1)
{
switch(dex)
{
case 0x01:
over = adcr;
break;
case 0x02:
over = adcg;
break;
case 0x03:
over = adcb;
break;
}
return over;
}
}
exti.h文件
#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
void Adc_Init(void);
u16 Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);
int get_adc(u8 dex);
#endif
exti.c文件
#include "sys.h"
#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
#include "stmflash.h"
#include "stdio.h"
#include "adc.h"
const u8 TEXT_Buffer[]={"STM32 FLASH TEST"};
#define SIZE1 sizeof(adc_value)
#define FLASH_SAVE_ADDR 0X08010000 //flash保存地址
int adc_value[3];//adc数据保存
int adc_read_value[3];//adc数据读取
int ChValue[3];
#define FILTER_Nn1 500
int Filter1()
{
int i, j;
long int filter_temp, filter_sum = 0;
int filter_buf[FILTER_Nn1];
for(i = 0; i < FILTER_Nn1; i++)
{
filter_buf[i] = get_adc(1);
}
for(j = 0; j < FILTER_Nn1 - 1; j++)
{
for(i = 0; i < FILTER_Nn1 - 1 - j; i++)
{
if(filter_buf[i] > filter_buf[i + 1])
{
filter_temp = filter_buf[i];
filter_buf[i] = filter_buf[i + 1];
filter_buf[i + 1] = filter_temp;
}
}
}
for(i = 40; i < FILTER_Nn1 - 40; i++)
filter_sum += filter_buf[i];
return filter_sum / (FILTER_Nn1 - 80);
}
int Filter2()
{
int i, j;
long int filter_temp, filter_sum = 0;
int filter_buf[FILTER_Nn1];
for(i = 0; i < FILTER_Nn1; i++)
{
filter_buf[i] = get_adc(2);
}
for(j = 0; j < FILTER_Nn1 - 1; j++)
{
for(i = 0; i < FILTER_Nn1 - 1 - j; i++)
{
if(filter_buf[i] > filter_buf[i + 1])
{
filter_temp = filter_buf[i];
filter_buf[i] = filter_buf[i + 1];
filter_buf[i + 1] = filter_temp;
}
}
}
for(i = 40; i < FILTER_Nn1 - 40; i++)
filter_sum += filter_buf[i];
return filter_sum / (FILTER_Nn1 - 80);
}
int Filter3()
{
int i, j;
long int filter_temp, filter_sum = 0;
int filter_buf[FILTER_Nn1];
for(i = 0; i < FILTER_Nn1; i++)
{
filter_buf[i] = get_adc(3);
}
for(j = 0; j < FILTER_Nn1 - 1; j++)
{
for(i = 0; i < FILTER_Nn1 - 1 - j; i++)
{
if(filter_buf[i] > filter_buf[i + 1])
{
filter_temp = filter_buf[i];
filter_buf[i] = filter_buf[i + 1];
filter_buf[i + 1] = filter_temp;
}
}
}
for(i = 40; i < FILTER_Nn1 - 40; i++)
filter_sum += filter_buf[i];
return filter_sum / (FILTER_Nn1 - 80);
}
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
EXTI_InitStructure.EXTI_Line=EXTI_Line1;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI0_IRQHandler(void)
{
delay_ms(10);
if(KEY0==0)
{
adc_value[0] =Filter1();
adc_value[1] =Filter2();
adc_value[2] =Filter3();
STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)adc_value,SIZE1);
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler(void)
{
delay_ms(10);
if(KEY1==0)
{
/*
printf("Start Read FLASH.... ");
STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)adc_value,SIZE1);
printf("The Data Readed Is: ");
printf("R=%d\n",adc_value[0]);
printf("G=%d\n",adc_value[1]);
printf("B=%d\n",adc_value[2]);
*/
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
stmflash.h文件
#ifndef __STMFLASH_H__
#define __STMFLASH_H__
#include "sys.h"
#define STM32_FLASH_SIZE 128 //所选stm32flash的容量大小
#define STM32_FLASH_WREN 1
#define STM32_FLASH_BASE 0x08000000 //STM32 FLASH起始地址
u16 STMFLASH_ReadHalfWord(u32 faddr);
void STMFLASH_WriteLenByte(u32 WriteAddr,u32 DataToWrite,u16 Len);
u32 STMFLASH_ReadLenByte(u32 ReadAddr,u16 Len);
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite);
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead);
void Test_Write(u32 WriteAddr,u16 WriteData);
#endif
stmflash.c文件
#include "stmflash.h"
#include "delay.h"
#include "usart.h"
u16 STMFLASH_ReadHalfWord(u32 faddr)
{
return *(vu16*)faddr;
}
#if STM32_FLASH_WREN
void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
u16 i;
for(i=0;i<NumToWrite;i++)
{
FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
WriteAddr+=2;
}
}
#if STM32_FLASH_SIZE<256
#define STM_SECTOR_SIZE 1024
#else
#define STM_SECTOR_SIZE 2048
#endif
u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
u32 secpos;
u16 secoff;
u16 secremain;
u16 i;
u32 offaddr;
if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;
FLASH_Unlock();
offaddr=WriteAddr-STM32_FLASH_BASE;
secpos=offaddr/STM_SECTOR_SIZE;
secoff=(offaddr%STM_SECTOR_SIZE)/2;
secremain=STM_SECTOR_SIZE/2-secoff;
if(NumToWrite<=secremain)secremain=NumToWrite;
while(1)
{
STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);
for(i=0;i<secremain;i++)
{
if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;
}
if(i<secremain)
{
FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);
for(i=0;i<secremain;i++)
{
STMFLASH_BUF[i+secoff]=pBuffer[i];
}
STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);
}else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);
if(NumToWrite==secremain)break;
{
secpos++;
secoff=0;
pBuffer+=secremain;
WriteAddr+=secremain;
NumToWrite-=secremain;
if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;
else secremain=NumToWrite;
}
};
FLASH_Lock();
}
#endif
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
{
u16 i;
for(i=0;i<NumToRead;i++)
{
pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);
ReadAddr+=2;
}
void Test_Write(u32 WriteAddr,u16 WriteData)
{
STMFLASH_Write(WriteAddr,&WriteData,1);
}
key.h文件
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)
#define KEY1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define KEY0_PRES 1
#define KEY1_PRES 2
void KEY_Init(void);
u8 KEY_Scan(u8);
#endif
key.c文件
#include "stm32f10x.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//ʹÄÜPORTA,PORTEʱÖÓ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;
if(mode)key_up=1;
if(key_up&&(KEY0==0||KEY1==0))
{
delay_ms(10);
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
}else if(KEY0==1&&KEY1==1)key_up=1;
return 0;
}
led.h文件
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED_R PCout(13)
#define LED_G PEout(5)
#define LED_B PCout(15)
void LED_Init(void);
#endif
led.c文件
#include "led.h"
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_13);
}
main.c文件
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "adc.h"
#include "led.h"
#include "exti.h"
#include "timer.h"
#include "math.h"
#include "stmflash.h"
#define SIZE1 sizeof(adc_value)
#define FLASH_SAVE_ADDR 0X08010000 //flash保存地址
int adcr,adcg,adcb,set=50;
extern int adc_value[3];
int main(void)
{
u8 t=0;
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
uart_init(115200);
EXTIX_Init();
Adc_Init();
LED_Init();
// KEY_Init();
STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)adc_value,SIZE1);
printf("The Data Readed Is: ");
printf("R=%d ",adc_value[0]);
printf("G=%d ",adc_value[1]);
printf("B=%d\n",adc_value[2]);
while(1)
{
if(t%10==0)
{
adcr=Get_Adc_Average(ADC_Channel_1,10);
adcg=Get_Adc_Average(ADC_Channel_2,10);
adcb=Get_Adc_Average(ADC_Channel_3,10);
printf("adcrgb:%d %d %d\n",adcr,adcg,adcb);
printf("R=%d ",adc_value[0]);
printf("G=%d ",adc_value[1]);
printf("B=%d\n",adc_value[2]);
}
if(((adc_value[0]-set)<=adcr&&adcr<=(adc_value[0]+set))&&((adc_value[1]-set)<=adcg&&adcg<=(adc_value[1]+set))&&((adc_value[2]-set)<=adcb&&adcb<=(adc_value[2]+set)))
{
LED_R=0;
delay_ms(10);
}
else
{
LED_R=1;
delay_ms(10);
}
delay_ms(10);
t++;
if(t==20)
{
t=0;
}
}
}
PS:由于作者水平有限,不足之处希望批评与指正!