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


http://s8.uploads.ru/t/4ubtL.png
http://sg.uploads.ru/t/uH7zG.jpg

Отредактировано CERGEI (2017-11-04 02:29:48)