Hi all,
I owned this one on taobao, not realy ghetto style, but I love mounting holes and am too lazy to solder, the price should be less than 2$.
Some thoughts :
I have CooCox and a cheap jlink debugger. If I use the on board crystal too, only 10 IOs will remain for use
They are only 2 gnd pins on the whole board, one on the SWD header and one on the uart header
If you use jlink for the first time in the session, you will be asked to select the device manually. Press the "yes" button, then select "ST", then select "STM32F030F4"
Here is some code that works:
/* STM32F030F4P6 chinese board application
* slave for Single-wire half-duplex communication
* waits for the master's request, then
* - converts the corresponding adc channel
* - reads the corresponding io pin
* - put the results into a byte and send the byte while setting an rs485 driver output enable
*
*
*/
#include <stdio.h>
#include <stm32f0xx.h>
#include <system_stm32f0xx.h>
#include <stm32f0xx_gpio.h>
#include <stm32f0xx_rcc.h>
#include <stm32f0xx_adc.h>
#include "stm32f0xx_misc.h"
#include "stm32f0xx_usart.h"
void adc_conv_s();
void gpio_init();
void adc_init ();
void usart_init();
volatile uint16_t user;
volatile uint16_t user1 = 110;
volatile uint8_t tab_speed[] = {0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,39,41,43,45,47,49,51,53,55,57,59,61,63,63,63,63,63,1,1,1,1};
volatile uint8_t usart_rx_d;
volatile uint8_t usart_tx_d;
int main (void) {
gpio_init();
adc_init ();
usart_init();
while (1) {
}
}
void USART1_IRQHandler(void)
{
GPIOA->BRR = GPIO_Pin_10; // Set PA10 Low -> rs485 Driver Output Disable
usart_tx_d = 128+64;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
/* Read one byte from the receive data register */
usart_rx_d = USART_ReceiveData(USART1);
switch (usart_rx_d) {
case 0x24:
ADC1->CHSELR = 1<<0;
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4)) {usart_tx_d = 128;}
adc_conv_s();
break;
case 0x25:
ADC1->CHSELR = 1<<1;
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5)) {usart_tx_d = 128;}
adc_conv_s();
break;
case 0x26:
ADC1->CHSELR = 1<<2;
if (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)) {usart_tx_d = 128;}
adc_conv_s();
break;
case 0x27:
ADC1->CHSELR = 1<<3;
if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)) {usart_tx_d = 128;}
adc_conv_s();
break; }
}
}
void adc_conv_s()
{
ADC_StartOfConversion(ADC1);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); /* Wait the ADCEN flag */ // why 2 times ?
GPIOA->BSRR = GPIO_Pin_10; // Set PA10 HIGH -> rs485 Driver Output Enable
ADC_StartOfConversion(ADC1);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); /* Wait the ADCEN flag */
usart_rx_d = ADC_GetConversionValue(ADC1);
usart_rx_d = tab_speed[usart_rx_d/2];
usart_tx_d += usart_rx_d;
USART_SendData(USART1, usart_tx_d );
}
void gpio_init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7); // input BUTTON S1,S2,S3
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure); // Initialises the GPIOA
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_1); // input BUTTON 4
GPIO_Init(GPIOB, &GPIO_InitStructure); // Initialises the GPIOB
}
void adc_init (void) {
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/* GPIOC Periph clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
/* ADC1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* Configure ADC Channel0 to 3 as analog input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ADC1 Configuration *******************************************************/
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b; /* Configure the ADC1 with a resolution equal to 8 bits*/
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_239_5Cycles); /* 239.5 Cycles as sampling time */
ADC_GetCalibrationFactor(ADC1); /* ADC Calibration */
ADC_Cmd(ADC1, ENABLE); /* Enable ADCperipheral */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); /* Wait the ADCEN flag */
ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_13_5Cycles); /* set the sample time */
// end of adc init code ...
}
void usart_init(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* Enable GPIO clock */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); /* Connect PXx to USARTx_Tx */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; /* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; /* Configure USART Rx as simple output function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); /* Enable USART clock */
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200; /* USART configuration */
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART1->CR3 |= 8; // set HDSEL -> Single-wire half-duplex communication
USART_Cmd(USART1, ENABLE); /* Enable USART */
NVIC_EnableIRQ(USART1_IRQn); //
NVIC_SetPriority(USART1_IRQn, 0); //
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// end of usart init code ...
}
/*
1 BOOT0
2 OSC_IN (PF0)
3 OSC_OUT (PF1)
4 NRST
5 VDD_A
6 PA0 USART1_CTS ; ADC_IN0,RTC_TAMP2,WKUP1
7 PA1 USART1_RTS,EVENTOUT ; ADC_IN1
8 PA2 USART1_TX ; ADC_IN2
9 PA3 USART1_RX ; ADC_IN3
10 PA4 SPI1_NSS,USART1_CK,TIM14_CH1 ; ADC_IN4
11 PA5 SPI1_SCK ; ADC_IN5
12 PA6 SPI1_MISO,TIM3_CH1,TIM1_BKIN,TIM16_CH1,EVENTOUT ; ADC_IN6
13 PA7 SPI1_MOSI,TIM3_CH2,TIM14_CH1,TIM1_CH1N,TIM17_CH1,EVENTOUT ; ADC_IN7
14 PB1 TIM3_CH4,TIM14_CH1,TIM1_CH3N ; ADC_IN9
15 VSS
16 VDD
17 PA9 USART1_TX,TIM1_CH2,I2C1_SCL
18 PA10 USART1_RX,TIM1_CH3,TIM17_BKIN,I2C1_SDA
19 PA13 IR_OUT,SWDIO
20 PA14 SWCLK
p1:
a4 button0 (led)-jumper-gnd
a3 adc3
a2 adc2
a1 adc1
a0 adc0
vdda
nrst
osc/o
osc/i
boot0
p2:
5v
3v3
a5 button1
a6 (b0t0)
a7 button2
b1 button3
a9 tx
a10 rx
a13 dio
a14 clk
j3:
gnd
tx tx/rx network
rx network -> rs485 Driver Output Enable
3v3
j4:
gnd
clk
dio
3v3
jumpers:
led
b0t0
vdda
*/
/* swd (jlink):
* bas :
* vert sous 1ère pin encoche
* haut (encoche) :
* jaune 2ème pin encoche
* orange à droite de jaune
* rouge dernière pin (sous triangle)
*/