Изучая 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)