This is the 25th day of my participation in the August Genwen Challenge.More challenges in August
STM8 microcontroller although it is 8 microcontroller, but the function is still very powerful, today to realize the analog watchdog function of STM8 microcontroller ADC.
The official introduction is as follows:
The function of the watchdog is well known, but what is this simulated watchdog? To put it simply, the analog watchdog can monitor the ADC sampled data in real time. When the sampled data value is less than the set minimum value or greater than the set maximum value, the microcontroller will trigger the ADC interrupt. This is very practical in temperature monitoring. For example, when the temperature value of the device is not in the set range, the interruption will be triggered automatically, without the need for the program to collect the value of the ADC channel all the time, and then use the software to judge whether the current temperature value exceeds the normal range.
Here is a demonstration of how this simulated watchdog function works:
#include "adc.h"
#include "main.h"
u16 DATAH = 0; //ADC converts 8 bits higher
u16 DATAL = 0; //ADC converts 8 bits lower
_Bool ADC_flag = 0; //ADC conversion success flag
// The AD channel pin is initialized
void ADC_GPIO_Init( void )
{
PD_DDR &= ~( 1 << 3 ); //PD3 is set to input current
PD_CR1 &= ~( 1 << 3 ); //PD3 is set to dangling input
}
void ADC_CH_Init( u8 ch )
{
char l = 0;
ADC_CR1 = 0x00; //fADC = fMASTER/2, 8Mhz single conversion, no conversion
ADC_CSR |= ch ; // Select AD input channel such as PD2(AIN3)
ADC_CR2 = 0x00; // By default, data is read high and low first
ADC_TDRL = ( 1 << ch ); // Disable schmidt trigger function 1 of corresponding channel by ch+1 bit
ADC_CR1 |= 0x01; // Enable ADC and start conversion
// Set the upper threshold value
ADC_HTRH = ( u8 )( 800 >> ( u8 )2 ); // Store the top 8 bits of 10 bits of data
ADC_HTRL = ( u8 )800; // Store the lower 8 bits of 10 bits of data
// Set the lower threshold
ADC_LTRH = ( u8 )( 300 >> ( u8 )2 ); // Store the top 8 bits of 10 bits of data
ADC_LTRL = ( u8 )300; // Store the lower 8 bits of 10 bits of data
ADC_CSR |= 0x10; // Enable watchdog interrupt
for( l = 0; l < 100; l++ ); // Delay to ensure that the ADC module is powered on for at least 7us
ADC_CR1 = ADC_CR1 | 0x01; // Again enable ADC at the lowest position 1 of register CR1 and begin conversion
}
// Collect PD2 voltage
u16 ReadVol_CH3( void )
{
u16 voltage = 0;
while( ( ADC_CSR & 0x80) = =0 ); // Wait for the conversion to finish
if( ADC_CSR & 0x80 )
{
DATAH = ADC_DRH; // Read the high 8 bits of the ADC result
DATAL = ADC_DRL; // Read the lower 8 bits of the ADC result
voltage = ( DATAH << 2 ) + DATAL ; // Get ten digit precision data 0--1024
ADC_CR1 = ADC_CR1 | 0x01; // Start the next conversion again with the CR1 register's lowest position 1
ADC_CSR &= 0x7F;
};
return voltage;
}
//AD interrupt service function Interrupt number 22
#pragma vector = 24 // Interrupt number in IAR, add 2 to interrupt number in STVD
__interrupt void ADC_Handle( void )
{
ADC_CSR &= ~0x40;
// Handle temperature anomalies
}
Copy the code
ADC uses single-trigger mode, and then sets the ADC_HTR register to the upper alarm value (800), and the ADC_LTRL register to the lower alarm value (300), that is, when the ADC sample value is greater than 800 or less than 300, the ADC will interrupt. Then set bit 4 of the ADC_CSR register, the AWDIE bit, to 1 to turn on the analog watchdog interrupt. The ADC sample values are then read looping through the main function.
The main program code is as follows:
#include "iostm8s103f3.h"
#include "led.h"
#include "adc.h"
void SysClkInit( void )
{
CLK_SWR = 0xe1; //HSI 16MHz CPU clock frequency of the primary clock source
CLK_CKDIVR = 0x00; //CPU clock is 0, system clock is 0
}
u16 val1 = 0;
void main( void )
{
SysClkInit();
__asm( "sim" ); // Disable interrupts
LED_GPIO_Init();
ADC_CH_Init( 3 );
__asm( "rim" ); // Enable interrupts
while( 1) { LED = ! LED;/ / samplingval1 = ReadVol_CH3(); }}Copy the code
Val1 is the sampled voltage value. Run the program at full speed and observe the sampled value in the observation window:
When the sampling voltage is between 300 and 800, the ADC interrupt function does not fire.
When the voltage value is below 300, the ADC interrupt is triggered at position 6 of the ADC_CSR register, indicating that an analog watchdog interrupt has been generated.
When the sample value is greater than 800, interrupts can also occur
After an interrupt occurs, manually clear the AWD flag in the interrupt.
One particular problem to note here is that when setting the upper and lower limits for the simulated watchdog, the high register stores the high 8 bits of the 10 bit value, and the low register stores the low 2 bits of the 10 bit value.
Please refer to the Register Settings in the English manual. The description of these four registers in the Chinese reference manual is wrong. If you follow the instructions in the Chinese manual, the simulated watchdog will never come out of the interrupt. Be careful.
The description of these registers in the Chinese manual is wrong
The Chinese reference manual here was downloaded from the official website of ST. I don’t know whether the official staff made some mistakes in writing or made some mistakes in translation. Be careful with this four-register setting when using the analog watchdog.