feat: auto read adc in SysTick_Handler

This commit is contained in:
liuyihui 2023-04-28 01:59:54 +08:00
parent c9af85ad08
commit 3f22ff1a07
7 changed files with 36 additions and 21 deletions

View File

@ -2,5 +2,10 @@
#include <inttypes.h>
#define ADC_M 1024
extern int16_t adc_buf[ADC_M];
extern int16_t pADC;
extern uint8_t fADC;
void adc0_Init();
int16_t adc0_TR_DATA();

View File

@ -27,10 +27,10 @@
PORT##port->PCR[pin] |= PORT_PCR_PE(0x1); \
}
#define ticks_ms (uint32_t)(ticks_10us / 100)
#define ticks_ms (uint32_t)(ticks_50us / 20)
extern uint32_t CORCLK;
extern uint32_t BUSCLK;
extern volatile uint32_t ticks_10us;
extern volatile uint32_t ticks_50us;
extern void SysTick_Handler(void);
extern void UART1_IRQHandler(void);

View File

@ -16,11 +16,11 @@ static inline bool timer_expired_ms(uint32_t *t, uint32_t prd) {
return true; // Expired, return true
}
static inline bool timer_expired_10us(uint32_t *t, uint32_t prd) {
if (ticks_10us + prd < *t) *t = 0; // Time wrapped? Reset timer
if (*t == 0) *t = ticks_10us + prd; // First poll? Set expiration
if (*t > ticks_10us) return false; // Not expired yet, return
*t = (ticks_10us - *t) > prd ? ticks_10us + prd : *t + prd; // Next expiration time
static inline bool timer_expired_50us(uint32_t *t, uint32_t prd) {
if (ticks_50us + prd < *t) *t = 0; // Time wrapped? Reset timer
if (*t == 0) *t = ticks_50us + prd; // First poll? Set expiration
if (*t > ticks_50us) return false; // Not expired yet, return
*t = (ticks_50us - *t) > prd ? ticks_50us + prd : *t + prd; // Next expiration time
return true; // Expired, return true
}
@ -29,7 +29,7 @@ static inline void delay_ms(uint32_t ms) {
while (ticks_ms - start < ms) asm("nop");
}
static inline void delay_10us(uint32_t us) {
uint32_t start = ticks_10us;
while (ticks_10us - start < us) asm("nop");
static inline void delay_50us(uint32_t us) {
uint32_t start = ticks_50us;
while (ticks_50us - start < us) asm("nop");
}

9
main.c
View File

@ -6,8 +6,6 @@
#include <stdio.h>
#include <string.h>
#define ADC_M 2048
int main(void) {
// Initialize
uart_init(UART_MSG, 9600); // Initialize UART1 with PC
@ -35,13 +33,14 @@ int main(void) {
uint16_t pos[x1 - x0 - 1];
uint16_t x = x0 + 1, y;
uint32_t timer = 0;
fADC = 1;
for (;;) {
if (timer_expired_10us(&timer, 5)) {
if (timer_expired_50us(&timer, 1)) {
LCD_DrawPoint(x, pos[x - x0 - 1], BACK_COLOR);
res = adc0_TR_DATA() - 1550;
y = ym + res * (y1 - ym) / ADC_M;
res = adc_buf[pADC];
y = ym + res * (y1 - ym) / 2048;
LCD_DrawPoint(x, y, RED);
LCD_DrawPoint(x, ym, BLACK);

View File

@ -1,6 +1,10 @@
#include "adc.h"
#include "derivative.h"
int16_t adc_buf[ADC_M];
int16_t pADC = 0;
uint8_t fADC = 0;
void adc0_Init() {
// Enable ADC0 and PORTE clock
SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
@ -9,10 +13,10 @@ void adc0_Init() {
// USE AD0 (ADC0_SE4a)
PORTE->PCR[21] |= PORT_PCR_MUX(0x0);
ADC0->CFG1 = ADC_CFG1_ADLSMP_MASK // Sample time 0 = Short, 1 = Long
ADC0->CFG1 = ADC_CFG1_ADLSMP(0x01) // Sample time 0 = Short, 1 = Long
| ADC_CFG1_MODE(0x01); // Conversion mode 00 = 8-bit, 01 = 12-bit, 10 = 10-bit, 11 = 16-bit
ADC0->SC3 = ADC_SC3_ADCO_MASK // Continuous Conversion if AVGE = 1
| ADC_SC3_AVGE_MASK // Hardware average
ADC0->SC3 = ADC_SC3_ADCO(0x01) // Continuous conversion enable
| ADC_SC3_AVGE(0x01) // Hardware average
| ADC_SC3_AVGS(0x01); // Hardware average 00 = 4 samples, 01 = 8, 10 = 16, 11 = 32
ADC0->SC1[0] = ADC_SC1_ADCH(0x04); // Input channel select, AD4a is selected as input
}

View File

@ -1,12 +1,19 @@
#include "adc.h"
#include "derivative.h"
#include "uart.h"
uint32_t CORCLK = CORCLK_DEFAULT;
uint32_t BUSCLK = BUSCLK_DEFAULT;
volatile uint32_t ticks_10us;
volatile uint32_t ticks_50us;
void SysTick_Handler(void) { ticks_10us++; }
void SysTick_Handler(void) {
ticks_50us++;
if (fADC) {
adc_buf[pADC] = adc0_TR_DATA() - 1550;
pADC = (pADC + 1) % ADC_M;
}
}
void UART1_IRQHandler(void) {
if (UART1->S1 & UART_S1_RDRF_MASK) {

View File

@ -159,7 +159,7 @@ __attribute__((naked, noreturn)) void _reset(void) {
copy_data();
clock_init();
SysTick_Config(CORCLK / 100000); // Period of systick timer : 10 us
SysTick_Config(CORCLK / 100000 * 5); // Period of systick timer : 50 us
main();
for (;;) (void)0;