精度還可以,有1mV的誤差,可以允許的。
下面把程序發出來讓大家審核,有什么完善的地方我一定做到,希望大家給出寶貴意見。
/**
******************************************************************************
* @file Project/main.c
* @author MCD Application Team
* @version V2.0.0
* @date 25-February-2011
* @brief Main program body
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* © COPYRIGHT 2011 STMicroelectronics
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
/* Private defines -----------------------------------------------------------*/
unsigned char const shumaguan[] = {0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90};
//ADCValue數組存放A/D采樣值,voltageADC為數字濾波后的結果
unsigned int ADCValue[20] = {0},voltageADC = 0;
//voltage為電壓計算結果,單位mV
unsigned int voltage = 0;
/* Private function prototypes -----------------------------------------------*/
void ADConvert(void);
void DigitalFiltering(void);
void Display(void);
void Delay(unsigned int t);
/* Private functions ---------------------------------------------------------*/
void main(void)
{
unsigned char i;
//PG口數碼管段選,PE口數碼管位選
GPIO_Init(GPIOG,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_HIGH_FAST);
GPIO_Init(GPIOE,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_HIGH_FAST);
/*ADC2配置為:
-連續轉換模式
-通道0(PB0)
-fADC = fmaster/2
-觸發模式為定時器
-觸發關
-數據右對齊
-選擇通道0上的施密特觸發器
-施密特觸發器關*/
ADC2_Init(ADC2_CONVERSIONMODE_CONTINUOUS,
ADC2_CHANNEL_0,
ADC2_PRESSEL_FCPU_D2,
ADC2_EXTTRIG_TIM,
DISABLE,
ADC2_ALIGN_RIGHT,
ADC2_SCHMITTTRIG_CHANNEL0,
DISABLE);
/* Infinite loop */
while (1)
{
//連續轉換20次
ADConvert();
//數字濾波
DigitalFiltering();
i = 200;
while(i --)
Display();
}
}
void ADConvert(void)
{
unsigned char count = 0;
//連續轉換
ADC2->CR1 |= 0x02;
ADC2_StartConversion();
while(count < 20)
{
//等待轉換結束
while(ADC2_GetFlagStatus() == RESET);
//清除轉換結束標志位
ADC2_ClearFlag();
ADCValue[count] = ADC2_GetConversionValue();
count++;
}
//關閉連續轉換
ADC2->CR1 &= ~0X02;
}
void DigitalFiltering(void)
{
unsigned char i,j;
unsigned int temp;
//對數組排序
for(i = 20;i >= 1;i--)
{
for(j = 0;j<(i-1);j++)
{
if(ADCValue[j] > ADCValue[j+1])
{
temp = ADCValue[j];
ADCValue[j] = ADCValue[j+1];
ADCValue[j+1] = temp;
}
}
}
//舍棄最大和最小的兩個數,然后求平均值
voltageADC = 0;
for(i = 2;i<=17;i++)
voltageADC += ADCValue[i];
voltageADC /= 16;
}
void Display(void)
{
unsigned char displayArray[4],i;
voltage = (unsigned int)((unsigned long)voltageADC * 3161UL / 1023UL);
//拆分數據,使用數碼管顯示
displayArray[3] = voltage / 1000;
displayArray[2] = (voltage % 1000) / 100;
displayArray[1] = (voltage % 100) / 10;
displayArray[0] = voltage % 10;
//使用數碼管顯示電壓值,單位mV
for(i = 0;i < 4;i++)
{
GPIOG->ODR = shumaguan[displayArray[i]];
GPIOE->ODR = ~(0X01 << i);
Delay(100);
GPIOE->ODR = 0XFF;
}
}
void Delay(unsigned int t)
{
while(t--);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/