removed garbage, added readme

master
Ondřej Hruška 9 years ago
parent 5285f16784
commit 02f77500ec
  1. 1
      Makefile
  2. 3
      README.md
  3. 77
      capture.c
  4. 10
      capture.h
  5. 3
      doc/controls.txt
  6. 1
      doc/output.txt
  7. 86
      init.c
  8. 1
      init.h
  9. 153
      main.c

@ -24,7 +24,6 @@ OBJS += utils/nvic.o
OBJS += utils/str_utils.o OBJS += utils/str_utils.o
OBJS += init.o OBJS += init.o
OBJS += blink.o OBJS += blink.o
OBJS += capture.o
OBJS += lib/common.o OBJS += lib/common.o
################################################################ ################################################################

@ -0,0 +1,3 @@
This is a bootstrap project for programming STM32L100 without any external libs (with just libc).
It uses `arm-none-eabi-gcc` and is written for STM32L100C-DISCOVERY.

@ -1,77 +0,0 @@
#include "capture.h"
#include "utils/timebase.h"
#include <math.h>
uint16_t adc_measure(uint8_t channel)
{
ADC1_SQR5 = channel; // select n-th channel
ADC1_SQR1 = 0; // sets length to 1 (0000)
ADC1_CR2 |= ADC_CR2_SWSTART; // start conversion
// wait for end of conversion
while (!(ADC1_SR & ADC_SR_EOC));
return ADC1_DR;
}
float measure_angle(void)
{
uint16_t d = adc_measure(18);
return -135 + 270 * (d / 4095.0f);
}
float measure_exposure(void)
{
uint16_t d = adc_measure(8);
float alpha = d / 4095.0f;
return alpha * 100; // %
}
float measure_resistance(void)
{
uint16_t d = adc_measure(9);
float alpha = d / 4095.0f;
float ref_r = 330;
return (ref_r * alpha) / (1 - alpha);
}
float measure_temp(void)
{
uint16_t ts_data = adc_measure(ADC_CH_TEMP);
// temperature calibration constants for L100 are undocumented,
// probably because the sensor is broken.
// Temperature sensor is unstable and unreliable.
uint16_t ts_cal1 = MMIO16(0x1FF800FA);
uint16_t ts_cal2 = MMIO16(0x1FF800FE);
return ((80.0f / (ts_cal2 - ts_cal1)) * (ts_data - ts_cal1) + 30.0f);
}
void pwm2_set_frequency(float hz)
{
float core_clk = 16000000 / 2.0f; // prescaller
float cnt = core_clk / hz;
uint32_t div = (uint32_t)cnt;
if (hz < 150) {
div /= 8;
TIM2_PSC = 15;
} else {
TIM2_PSC = 1;
}
TIM2_ARR = div; // sets frequency
TIM2_CCR2 = TIM2_ARR/2; // duty cycle
}

@ -1,10 +0,0 @@
#pragma once
#include <common.h>
uint16_t adc_measure(uint8_t channel);
float measure_temp(void);
float measure_angle(void);
float measure_resistance(void);
float measure_exposure(void);
void pwm2_set_frequency(float hz);

@ -1,3 +0,0 @@
b,d - změna střídy PWM, krok 50 (rozsah 0-1000)
m,n - změna hodnoty DAC, krok 117 (rozsah 0-4095)
g - nulovat počítadlo závory

@ -1 +0,0 @@
T -179.6°C | An -6.6° | R 589.2 | L 1.8% | G 0, #0 | DA 4095 | PWM 1000

@ -4,17 +4,15 @@
#include "utils/usart.h" #include "utils/usart.h"
#include "utils/nvic.h" #include "utils/nvic.h"
// This file contains examples of initializing some peripherals
void init_gpios(void) void init_gpios(void)
{ {
gpio_enable(GPIOA);
gpio_enable(GPIOB);
gpio_enable(GPIOC); gpio_enable(GPIOC);
// LEDs // LEDs
gpio_set_mode(GPIOC, BIT8 | BIT9, MODER_OUTPUT); gpio_set_mode(GPIOC, BIT8 | BIT9, MODER_OUTPUT);
gpio_set_mode(GPIOC, BIT11, MODER_INPUT);
} }
@ -42,7 +40,7 @@ void init_usart(void)
{ {
gpio_set_af(GPIOA, BIT2 | BIT3, AF7); gpio_set_af(GPIOA, BIT2 | BIT3, AF7);
// USART at A2 (tx), A3 (rx) // USART2 at A2 (tx), A3 (rx)
RCC_APB1ENR |= RCC_APB1ENR_USART2EN; RCC_APB1ENR |= RCC_APB1ENR_USART2EN;
// RATE 9600Bd 104.1875 (see datasheet for reference) // RATE 9600Bd 104.1875 (see datasheet for reference)
@ -61,24 +59,18 @@ void init_usart(void)
void init_systick(void) void init_systick(void)
{ {
//SysTick_CSR = (SysTick_CSR & ~SysTick_CSR_CLKSOURCE) | (1 << __CTZ(SysTick_CSR_CLKSOURCE));
patch_register(SysTick_CSR, SysTick_CSR_CLKSOURCE, 1); // 1 - core, 0 - div 8 patch_register(SysTick_CSR, SysTick_CSR_CLKSOURCE, 1); // 1 - core, 0 - div 8
SysTick_RELOAD = 16000; // 1ms interrupt @ 16MHz core clock SysTick_RELOAD = 16000; // 1ms interrupt @ 16MHz core clock
SysTick_CSR |= SysTick_CSR_TICKINT | SysTick_CSR_ENABLE; SysTick_CSR |= SysTick_CSR_TICKINT | SysTick_CSR_ENABLE;
} }
// ----
void init_adc(void) void init_adc(void)
{ {
// B1 ... AN9 Vcc o--[330R]--(B1)--[?R]--| GND gpio_set_mode(GPIOB, BIT1 | BIT0 | BIT12, MODER_ANALOG); // configure pins you want to use
// B0 ... AN8 fototransistor
// B12 .. AN18 "angle" potentiometer
// C5 ... AN15
gpio_set_mode(GPIOB, BIT1 | BIT0 | BIT12, MODER_ANALOG);
//gpio_set_mode(GPIOC, BIT5, MODER_ANALOG);
// enable clock for ADC // enable clock for ADC
RCC_APB2ENR |= RCC_APB2ENR_ADC1EN; RCC_APB2ENR |= RCC_APB2ENR_ADC1EN;
@ -98,6 +90,22 @@ void init_adc(void)
while (!(ADC1_SR & ADC_SR_ADONS)); while (!(ADC1_SR & ADC_SR_ADONS));
} }
// EXAMPLE to measure an ADC channel
uint16_t adc_measure(uint8_t channel)
{
ADC1_SQR5 = channel; // select n-th channel
ADC1_SQR1 = 0; // sets length to 1 (0000)
ADC1_CR2 |= ADC_CR2_SWSTART; // start conversion
// wait for end of conversion
while (!(ADC1_SR & ADC_SR_EOC));
return ADC1_DR;
}
// ----
void init_dac(void) void init_dac(void)
{ {
@ -117,7 +125,7 @@ void init_pwm1(void)
RCC_APB1ENR |= RCC_APB1ENR_TIM3EN; RCC_APB1ENR |= RCC_APB1ENR_TIM3EN;
// using timer 3, channel 1 // using timer 3, channel 1
gpio_set_af(GPIOA, BIT6, AF2); gpio_set_af(GPIOA, BIT6, AF2); // A6 PWM output
patch_register(TIM3_CCMR1, TIM_CCMR1_OC1M, TIM_OCM_PWM1); // set PWM1 mode patch_register(TIM3_CCMR1, TIM_CCMR1_OC1M, TIM_OCM_PWM1); // set PWM1 mode
@ -139,51 +147,3 @@ void init_pwm1(void)
TIM3_CR1 |= TIM_CR1_CEN; // enable timer. TIM3_CR1 |= TIM_CR1_CEN; // enable timer.
} }
// pwm with variable frequency
void init_pwm2(void)
{
// enable clock for the timer
RCC_APB1ENR |= RCC_APB1ENR_TIM2EN;
// using timer 2, channel 2 - PA1
gpio_set_af(GPIOA, BIT1, AF1);
patch_register(TIM2_CCMR1, TIM_CCMR1_OC2M, TIM_OCM_PWM1); // set PWM1 mode
TIM2_CCMR1 |= TIM_CCMR1_OC2PE; // preload enable
TIM2_CR1 |= TIM_CR1_ARPE; // auto reload is buffered
TIM2_CCER |= TIM_CCER_CC2E; // enable output compare (PWM output)
patch_register(TIM2_CR1, TIM_CR1_CMS, TIM_CMS_EDGE); // centering mode
patch_register(TIM2_CR1, TIM_CR1_DIR, 0); // count upwards only
// frequency set to 16 kHz
/*
TIM2_PSC = 32; // prescaller
TIM2_ARR = 1000; // sets frequency
TIM2_CCR2 = 500; // duty cycle
*/
TIM2_PSC = 1; // prescaller
TIM2_ARR = 1600; // sets frequency
TIM2_CCR2 = 500; // duty cycle
// generate update event to latch the value registers
TIM2_EGR |= TIM_EGR_UG;
TIM2_CR1 |= TIM_CR1_CEN; // enable timer.
}

@ -8,4 +8,3 @@ void init_systick(void);
void init_adc(void); void init_adc(void);
void init_dac(void); void init_dac(void);
void init_pwm1(void); void init_pwm1(void);
void init_pwm2(void);

153
main.c

@ -9,16 +9,6 @@
#include "init.h" #include "init.h"
#include "blink.h" #include "blink.h"
#include "capture.h"
// Gate state
static bool gate_closed = false;
static uint32_t gate_cnt = 0;
static float exposure_out, exposure_accum;
static uint32_t exposure_cnt;
static uint32_t pwm2_f = 50;
/** IRQ */ /** IRQ */
void USART2_IRQHandler(void) void USART2_IRQHandler(void)
@ -34,80 +24,14 @@ void USART2_IRQHandler(void)
// handle incoming char. // handle incoming char.
char c = usart_rx_char(USART2); char c = usart_rx_char(USART2);
uint32_t pwm2_f_old = pwm2_f; // echo
usart_tx_char(USART2, c);
switch (c) {
case 'g': // nulovat pocitadlo preruseni
gate_cnt = 0;
break;
case 'm': // zvysit DAC hodnotu
if (DAC_DHR12R1 < 4095) DAC_DHR12R1 += 117;
break;
case 'n': // snizit DAC hodnotu
if (DAC_DHR12R1 > 0) DAC_DHR12R1 -= 117;
break;
case 'b': // zvysit PWM stridu
if (TIM3_CCR1 < 1000) TIM3_CCR1 += 50;
break;
case 'd': // snizit PWM stridu
if (TIM3_CCR1 > 0) TIM3_CCR1 -= 50;
break;
case 'f': // zvysit PWM stridu
if (pwm2_f < 20000) pwm2_f += 10;
break;
case 's': // snizit PWM stridu
if (pwm2_f > 20) pwm2_f -= 10;
break;
case 'F': // zvysit PWM stridu
if (pwm2_f < 20000-100) pwm2_f += 100;
break;
case 'S': // snizit PWM stridu
if (pwm2_f > 100) {
pwm2_f -= 100;
} else {
pwm2_f = 20;
}
if (pwm2_f < 20) pwm2_f = 20;
break;
default:
break;
}
if (pwm2_f_old != pwm2_f) {
pwm2_set_frequency(pwm2_f);
}
USART2_SR ^= USART_SR_RXNE; USART2_SR ^= USART_SR_RXNE;
} }
} }
// Gate close handler
void gate_close(void)
{
gate_closed = 1;
gate_cnt++;
}
// Gate open handler
void gate_open(void)
{
gate_closed = 0;
}
/** Init peripherals; Called by startup script, before main() */ /** Init peripherals; Called by startup script, before main() */
void SystemInit(void) void SystemInit(void)
{ {
@ -118,82 +42,15 @@ void SystemInit(void)
init_adc(); init_adc();
init_dac(); init_dac();
init_pwm1(); init_pwm1();
init_pwm2();
pwm2_set_frequency(50);
register_periodic_task(green_toggle, 1000); // indicate running state
register_debounced_pin(GPIOB, 11, gate_close, gate_open); // gate handler
} }
int main(void) int main(void)
{ {
char buf[200]; usart_tx_string(USART2, "Hello.\n");
usart_tx_string(USART2, "DAQ system started.\n");
delay_ms(100);
bool first = true;
while (1) { while (1) {
float cels = measure_temp(); delay_ms(500);
float angle = measure_angle(); green_toggle();
float resis = measure_resistance();
float expos = measure_exposure();
// --- exposure averaging
exposure_accum += expos;
exposure_cnt++;
if (exposure_cnt >= 5) {
exposure_out = exposure_accum / exposure_cnt;
exposure_accum = 0;
exposure_cnt = 0;
}
if (first) {
exposure_out = expos; // pretend it's averaged
}
// ---
buf_reset(buf);
buf_append_str(buf, "T ");
buf_append_flt(buf, cels, 1);
buf_append_str(buf, "°C | ");
buf_append_str(buf, "An ");
buf_append_flt(buf, angle, 1);
buf_append_str(buf, "° | ");
buf_append_str(buf, "R ");
buf_append_flt(buf, resis, 1);
buf_append_str(buf, " | ");
buf_append_str(buf, "L ");
buf_append_flt(buf, exposure_out, 1);
buf_append_str(buf, "% | ");
buf_append_str(buf, "G ");
buf_append_str(buf, gate_closed ? "1" : "0");
buf_append_str(buf, ", #");
buf_append_int(buf, gate_cnt);
buf_append_str(buf, " | ");
buf_append_str(buf, "DA ");
buf_append_int(buf, DAC_DHR12R1);
buf_append_str(buf, " | ");
buf_append_str(buf, "PWM ");
buf_append_int(buf, TIM3_CCR1);
buf_append_str(buf, "\n");
usart_tx_string(USART2, buf);
delay_ms(100);
first = false;
} }
} }

Loading…
Cancel
Save