Изучая USART с DMA захотел попробовать связать компьютер и микроконтроллер ради обучения и интереса.
Может кому будет полезно или как начала для написания обмена с компьютером.
Пример основан на энкодере таймера 1,также задействовал 2 таймер для индикации работы платы. Таймер SysTik для отправки информации по энкодеру.
Программку написал простенькую.Писал в PyCharm,графическая оболочка tkinter.
Открытие порта,считывание энкодера и запись числа в энкодер. К тому же энкодер добавляет за один щелчке на +2 и середина энкодера равна 30000.
Может немного сыровато 
Keil
stm32f103c8t6
main.c
#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
#include "stdlib.h"
void init_enkoder_tim1(void);
#define TIMx_CLK 72000000UL // Hz
#define TIMx_Internal_Frequency 10000UL // Hz
#define TIMx_Out_Frequency 1UL // Hz
#define Prescaler (TIMx_CLK /TIMx_Internal_Frequency)-1UL
#define Period (TIMx_Internal_Frequency/TIMx_Out_Frequency)-1UL
uint32_t mig,flag_tik,flag_err,delay_tick,flag_tick,ccr4;
char flag_err_enkoder=0,flag_rx=0,flag_tx=1,flag_tx_end=0;
uint32_t testt=0;
char tx[15];
char rx[15];
int priem_rx;
void NMI_Handler(void)
{
// otkaz HSE
if(RCC->CIR & RCC_CIR_CSSF)
{
RCC->CIR |= RCC_CIR_CSSC; // ??????? ???? CSS
GPIOA->BSRR|=GPIO_BSRR_BS0;
flag_err=1;
}
}
void USART1_IRQHandler(void)
{
if( USART1->SR & USART_SR_TC)
{
flag_tx=1;
}
}
// pered usart1 tx
void DMA1_Channel4_IRQHandler(void)
{
if( DMA1->ISR & DMA_ISR_TCIF4)
{
DMA1->IFCR |= DMA_IFCR_CTCIF4;
flag_tx_end=1;
}
}
// priem usart1 rx
void DMA1_Channel5_IRQHandler(void)
{
if( DMA1->ISR & DMA_ISR_TCIF5)
{
DMA1->IFCR |= DMA_IFCR_CTCIF5;
flag_rx=1;
}
}
void TIM2_IRQHandler (void)
{
if(TIM2->SR & TIM_SR_UIF)
{
GPIOC->ODR ^= GPIO_ODR_ODR13;
TIM2->SR &= ~TIM_SR_UIF;
}
}
void TIM1_UP_IRQHandler(void) // perepolnenie tim enkoder
{
if(TIM1->SR & TIM_SR_UIF)
{
flag_err_enkoder=1;
TIM1->SR &= ~TIM_SR_UIF;
}
}
void SysTick_Handler(void) // 1 ms
{
//
delay_tick++;
if(delay_tick==500)
{
// off channel4 dma1 tx
DMA1_Channel4->CCR &= ~DMA_CCR4_EN ;
USART1->CR3 &= ~USART_CR3_DMAT ;
flag_tx=1;
delay_tick=0;
flag_tick=1;
}
}
int main(void)
{
//enable CSS
RCC->CR |= RCC_CR_CSSON ;
// taktirovanie
RCC->APB2ENR|=RCC_APB2ENR_AFIOEN; // tatirovanie alternativ
RCC->APB2ENR|=RCC_APB2ENR_IOPAEN;
RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;
RCC->APB2ENR|=RCC_APB2ENR_IOPCEN;
// RCC->APB1ENR|=RCC_APB1ENR_I2C1EN; // taktirovanie i2c
RCC->APB2ENR|=RCC_APB2ENR_TIM1EN; // TIM1
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // TIM2
// miganie PC13
GPIOC->CRH&=~GPIO_CRH_MODE13;
GPIOC->CRH|=GPIO_CRH_MODE13_1; // 50 mhz
GPIOC->CRH|=GPIO_CRH_MODE13_0;
GPIOC->CRH&=~GPIO_CRH_CNF13;
// 1 mC
SysTick_Config(SystemCoreClock /1000);
TIM2->PSC = Prescaler;
TIM2->ARR = Period ;
TIM2->DIER |= TIM_DIER_UIE;
NVIC_SetPriority(TIM2_IRQn,0);
NVIC_EnableIRQ(TIM2_IRQn);
TIM2->CR1|=TIM_CR1_CEN;
init_enkoder_tim1();
init_usart1();
// on channel5 dma rx
DMA1_Channel5->CCR |= DMA_CCR5_EN ;
USART1->CR3 |= USART_CR3_DMAR ;
while(1)
{
if(flag_tx)
{
// // off channel4 dma1 tx
DMA1_Channel4->CCR &= ~DMA_CCR4_EN ;
USART1->CR3 &= ~USART_CR3_DMAT ;
testt=TIM1->CNT;
sprintf(tx,"enkoder %d \n ",testt);
// zapuck kanala
DMA1_Channel4->CNDTR = 15;
DMA1_Channel4->CCR |= DMA_CCR4_EN ;
USART1->CR3 |= USART_CR3_DMAT ;
USART1->DR = *tx;
flag_tx=0;
}
if(flag_rx)
{
// off channel5 dma rx
DMA1_Channel5->CCR &= ~DMA_CCR5_EN ;
USART1->CR3 &= ~USART_CR3_DMAR ;
priem_rx=atoi(rx);
TIM1->CNT = priem_rx ;
flag_rx=0;
DMA1_Channel5->CNDTR = 5;
// on channel5 dma rx
DMA1_Channel5->CCR |= DMA_CCR5_EN ;
USART1->CR3 |= USART_CR3_DMAR ;
}
mig=1;
mig=0;
}
}
void init_enkoder_tim1(void)
{
TIM1->CNT = 30000 ;
TIM1->ARR = 65000 ; //
// enkoder
// input float a8,a9
GPIOA->CRH&=~GPIO_CRH_MODE8; // input
GPIOA->CRH&=~GPIO_CRH_CNF8;
GPIOA->CRH|=GPIO_CRH_CNF8_0; // 01- input float
GPIOA->CRH&=~GPIO_CRH_MODE9; // input
GPIOA->CRH&=~GPIO_CRH_CNF9;
GPIOA->CRH|=GPIO_CRH_CNF9_0; // 01- input float
//
TIM1->CCMR1|= TIM_CCMR1_CC1S_0|TIM_CCMR1_CC2S_0 ; // IC2 is mapped on TI2
// IC1 is mapped on TI1
TIM1->CCMR1 |= TIM_CCMR1_IC1F | TIM_CCMR1_IC2F; // filtr
TIM1->SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 ; // SMS=011
NVIC_SetPriority(TIM1_UP_IRQn ,0);
NVIC_EnableIRQ(TIM1_UP_IRQn);
TIM1->CR1 |= TIM_CR1_CEN;
}
usart.h
#ifndef _USART1 #define _USART1 #include "stm32f10x.h" // usart1 #define APBCLK 72000000UL #define BAUDRATE 115200UL extern char rx[15]; extern char tx[15]; void init_usart1(void); void USART1_str (const char *); #endif
usart.c
#include "usart.h"
void init_usart1(void)
{
RCC->APB2ENR|=RCC_APB2ENR_AFIOEN; // tatirovanie alternativ
RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// taktir usart in APB2= 72 Mhz
RCC->APB2ENR|= RCC_APB2ENR_USART1EN; // tatirovanie usart1
// remap usart1 na PB6-TX PB7-RX
AFIO->MAPR |= AFIO_MAPR_USART1_REMAP ;
// output TX- altern push-pull RX- input float
GPIOB->CRL&=~GPIO_CRL_MODE7; // input 00 - input
GPIOB->CRL&=~GPIO_CRL_CNF7;
GPIOB->CRL|=GPIO_CRL_CNF7_0; // 01- input float
GPIOB->CRL&=~GPIO_CRL_MODE6; // output mode=10- max speed 2mhz
GPIOB->CRL|=GPIO_CRL_MODE6_1;
GPIOB->CRL&=~GPIO_CRL_CNF6;
GPIOB->CRL|=GPIO_CRL_CNF6_1; // 10-alter push-pull 10= cnf
// // TX-PA9 RX-PA10
//
//
// GPIOA->CRH&= ~(GPIO_CRH_MODE9);
// GPIOA->CRH|=GPIO_CRH_MODE9_0|GPIO_CRH_MODE9_1;
// GPIOA->CRH&= ~(GPIO_CRH_CNF9);
// GPIOA->CRH|= GPIO_CRH_CNF9_0|GPIO_CRH_CNF9_1;
USART1->BRR = (APBCLK+BAUDRATE/2)/BAUDRATE;
USART1->CR1 |= USART_CR1_RE|USART_CR1_TE;
//////////////////////////////////////////////////////////////////////////
// DMA1 4-TX 5-RX
// DMA1 4-TX peredscha i priem po 8 bit
DMA1_Channel4->CPAR = (uint32_t) &(USART1->DR) ;
DMA1_Channel4->CMAR = (uint32_t) &tx ;
DMA1_Channel4->CNDTR = 15;
DMA1_Channel4->CCR = 0;
DMA1_Channel4->CCR |= DMA_CCR4_MINC | DMA_CCR4_DIR | DMA_CCR4_TCIE ;
// // zapuck kanala
// DMA1_Channel4->CCR |= DMA_CCR4_EN ;
// USART1->CR3 |= USART_CR3_DMAT ;
// USART1->DR = *tx;
//-----------------------------------------------------
// // po prerivanie dma1
// pered usart1 tx
//void DMA1_Channel4_IRQHandler(void)
//{
// if( DMA1->ISR & DMA_ISR_TCIF4)
// {
// DMA1->IFCR |= DMA_IFCR_CTCIF4;
// flag_tx=1;
// }
//}
//---------------------------------------------------
// // off channel4 dma1 tx
// DMA1_Channel4->CCR &= ~DMA_CCR4_EN ;
// USART1->CR3 &= ~USART_CR3_DMAT ;
//---------------------------------------------------------------------------
// DMA 5-RX
// Po DMA TCIF flag end peredchi
DMA1_Channel5->CPAR = (uint32_t) &(USART1->DR) ;
DMA1_Channel5->CMAR = (uint32_t) &rx ;
DMA1_Channel5->CNDTR = 5;
DMA1_Channel5->CCR = 0;
DMA1_Channel5->CCR |= DMA_CCR4_MINC|DMA_CCR5_TCIE ;
// zapusk kanala
//-----------------------------------------------------------
// on channel5 dma rx
// DMA1_Channel5->CCR |= DMA_CCR5_EN ;
// USART1->CR3 |= USART_CR3_DMAR ;
//------------------------------------------------------
// prerivanie po priemy DMA1_Channel5->CNDTR = 8; 8 bit
// priem usart1 rx
//void DMA1_Channel5_IRQHandler(void)
//{
// if( DMA1->ISR & DMA_ISR_TCIF5)
// {
// DMA1->IFCR |= DMA_IFCR_CTCIF5;
// flag_rx=1;
// }
//}
//-------------------------------------------------------
// off channel5 dma rx
// DMA1_Channel5->CCR &= ~DMA_CCR5_EN ;
// USART1->CR3 &= ~USART_CR3_DMAR ;
NVIC_SetPriority(DMA1_Channel4_IRQn ,0);
NVIC_EnableIRQ(DMA1_Channel4_IRQn);
NVIC_SetPriority(DMA1_Channel5_IRQn ,0);
NVIC_EnableIRQ(DMA1_Channel5_IRQn);
USART1->CR1 |= USART_CR1_UE ;
}
void Usart_Transmit(uint8_t Data)
{
while(!(USART1->SR & USART_SR_TC));
USART1->DR = Data;
}
void USART1_str (const char * data)
{
while((*data )){
Usart_Transmit (*data);
data++;
}
}
Исходник питон
import tkinter as tk
import time
import serial
import io
root=tk.Tk()
root.title('Usart-stm32')
root.geometry('200x400')
root['bg']='blue'
# переменые
#com_port=''
label_text='None'
flag_open=0
def init_com(event):
com_port=ent_com.get()
global ser
global flag_open
ser = serial.Serial()
ser.baudrate = 115200
ser.port = 'COM' + str(com_port)
try:
ser.open()
except Exception:
flag_open = 0
label4['text'] = 'Error'
else:
label4['text'] = 'COM' + str(com_port)
ser.flushInput()
#s = ser.read(15)
global flag_open
flag_open=1
def tick():
global flag_open
label.after(200, tick)
if(flag_open):
if(ser.inWaiting() > 0):
temp_ser=ser.read(15)
temp_ser3=temp_ser.decode().replace('\n\x00','')
index_ser=temp_ser3.rfind('r')
#print(temp_ser3[index_ser+1:])
temp_enk=(int(temp_ser3[index_ser+1:])-30000)/2
label['text'] = str(temp_enk)
else: label['text'] = 'No'
def in_stm32(event):
global ser
global flag_open
set_stm32=int(ent.get())
set_stm32=str(30000+(set_stm32*2))
print(set_stm32)
b_set_stm32=set_stm32.encode('ascii')
if(flag_open):
ser.write(b_set_stm32)
label4=tk.Label(root,text='COM?',font='sans 20',bg='black',fg='white',bd=5)
ent_com=tk.Entry(root,width=5,font='sans 20',bd=3)
but_com=tk.Button(root,width=8,text='COM',font='sans 20',bd=5)
but_com.bind('<Button-1>',init_com)
label2=tk.Label(root,text='Enkoder',font='sans 20',bg='black',fg='white',bd=5)
label = tk.Label(root,font='sans 20')
label3=tk.Label(root,text='In stm32',font='sans 20',bg='black',fg='white',bd=5)
ent = tk.Entry(root,width=8,font='sans 20',bd=3)
but=tk.Button(root,width=8,text='in',font='sans 20')
but.bind('<Button-1>',in_stm32)
label4.pack()
ent_com.pack()
but_com.pack()
label2.pack()
label.pack()
label3.pack()
ent.pack()
but.pack()
label.after_idle(tick)
root.mainloop()Отредактировано CERGEI (2017-11-04 02:29:48)

