查看: 297|回复: 2
收起左侧

[开源硬件] GRBL八:STM32代码移植——串口

[复制链接]

110

主题

578

帖子

1766

积分

助理工程师

 楼主| 发表于 2017-7-8 13:35 | 显示全部楼层 |返回版面||阅读模式
串口部分的一直只需要修改底层的串口代码就好包括串口初始化,读写函数,中断服务函数
serial.c
[cpp] view plain copy

  • /*
  •   serial.c - Low level functions for sending and recieving bytes via the serial port
  •   Part of Grbl
  •   The MIT License (MIT)
  •   GRBL(tm) - Embedded CNC g-code interpreter and motion-controller
  •   Copyright (c) 2009-2011 Simen Svale Skogsrud
  •   Copyright (c) 2011-2012 Sungeun K. Jeon
  •   Permission is hereby granted, free of charge, to any person obtaining a copy
  •   of this software and associated documentation files (the "Software"), to deal
  •   in the Software without restriction, including without limitation the rights
  •   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  •   copies of the Software, and to permit persons to whom the Software is
  •   furnished to do so, subject to the following conditions:
  •   The above copyright notice and this permission notice shall be included in
  •   all copies or substantial portions of the Software.
  •   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  •   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  •   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  •   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  •   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  •   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  •   THE SOFTWARE.
  • */  
  • #include <stm32f10x_lib.h>  
  • //#include "stm32f10x.h"  
  • #include "serial.h"  
  • #include "config.h"  
  • #include "motion_control.h"  
  • #include "protocol.h"  
  •   
  • uint8_t serial_rx_buffer[RX_BUFFER_SIZE];  
  • uint8_t serial_rx_buffer_head = 0;  
  • volatile uint8_t serial_rx_buffer_tail = 0;  
  •   
  • uint8_t serial_tx_buffer[RX_BUFFER_SIZE];  
  • uint8_t serial_tx_buffer_head = 0;  
  • volatile uint8_t serial_tx_buffer_tail = 0;  
  •   
  • #ifdef ENABLE_XONXOFF  
  •   volatile uint8_t flow_ctrl = XON_SENT; // Flow control state variable  
  •    
  •   // Returns the number of bytes in the RX buffer. This replaces a typical byte counter to prevent  
  •   // the interrupt and main programs from writing to the counter at the same time.  
  •   static uint8_t get_serial_rx_buffer_count()  
  •   {  
  •     if (serial_rx_buffer_head == serial_rx_buffer_tail) { return(0); }  
  •     if (serial_rx_buffer_head < serial_rx_buffer_tail) { return(serial_rx_buffer_tail-serial_rx_buffer_head); }  
  •     return (RX_BUFFER_SIZE - (serial_rx_buffer_head-serial_rx_buffer_tail));  
  •   }  
  • #endif  
  •   
  • void USART_Configuration(void)  
  • {   
  •    
  •   GPIO_InitTypeDef GPIO_InitStructure;  
  •   USART_InitTypeDef USART_InitStructure;   
  •   
  • /********************以下为USART1配置**************************/  
  •   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO,ENABLE);  
  •   /*
  •   *  USART1_TX -> PA9 , USART1_RX ->  PA10
  •   */                  
  •   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;            
  •   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
  •   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  •   GPIO_Init(GPIOA, &GPIO_InitStructure);            
  •   
  •   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;              
  •   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   
  •   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
  •   GPIO_Init(GPIOA, &GPIO_InitStructure);  
  •   
  •   USART_InitStructure.USART_BaudRate = 115200;  
  •   USART_InitStructure.USART_WordLength = USART_WordLength_9b;//9位数据  
  •   USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位  
  •   USART_InitStructure.USART_Parity = USART_Parity_Even;//偶校验  
  •   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能  
  •   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送和接受使能  
  •   USART_Init(USART1, &USART_InitStructure);   
  •   
  •   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  
  • //  USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  
  •    
  •   /***********************************************************************************
  •       void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState)
  •       使能或者失能USART外设
  •       USARTx:x可以是1,2或者3,来选择USART外设
  •       NewState: 外设USARTx的新状态
  •       这个参数可以取:ENABLE或者DISABLE
  •   ***********************************************************************************/  
  •   USART_Cmd(USART1, ENABLE);   
  •   USART_ClearITPendingBit(USART1, USART_IT_TC);//清除中断TC位              
  •   MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级   
  • }   
  •   
  • /***********************************************************************
  • 函数名称:void USART1_IRQHandler(void)  
  • 功    能:串口中断服务函数
  • ***********************************************************************/  
  • void USART1_IRQHandler(void)   
  • {  
  •     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收寄存器非空  
  •     {     
  •         uint8_t data = USART1->DR;  
  •         uint8_t next_head;  
  •    
  •         // Pick off runtime command characters directly from the serial stream. These characters are  
  •         // not passed into the buffer, but these set system state flag bits for runtime execution.  
  •         switch (data) {  
  •           case CMD_STATUS_REPORT: sys.execute |= EXEC_STATUS_REPORT; break; // Set as true  
  •           case CMD_CYCLE_START:   sys.execute |= EXEC_CYCLE_START; break; // Set as true  
  •           case CMD_FEED_HOLD:     sys.execute |= EXEC_FEED_HOLD; break; // Set as true  
  •           case CMD_RESET:         mc_reset(); break; // Call motion control reset routine.  
  •           default: // Write character to buffer      
  •             next_head = serial_rx_buffer_head + 1;  
  •             if (next_head == RX_BUFFER_SIZE) { next_head = 0; }  
  •       
  •             // Write data to buffer unless it is full.  
  •             if (next_head != serial_rx_buffer_tail) {  
  •                 serial_rx_buffer[serial_rx_buffer_head] = data;  
  •                 serial_rx_buffer_head = next_head;      
  •          
  •             }  
  •         }         
  •     //  USART_ClearITPendingBit(USART1, USART_IT_RXNE);  
  •   
  •     }  
  •     if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)   //写数据寄存器空,可以写数据  
  •     {  
  •          // Temporary serial_tx_buffer_tail (to optimize for volatile)  
  •           uint8_t tail = serial_tx_buffer_tail;  
  •             
  •             // Send a byte from the buffer   
  •             USART1->DR = serial_tx_buffer[tail];  
  •             
  •             // Update tail position  
  •             tail++;  
  •             if (tail == TX_BUFFER_SIZE) { tail = 0; }  
  •             
  •             serial_tx_buffer_tail = tail;  
  •             
  •             
  •           // Turn off Data Register Empty Interrupt to stop tx-streaming if this concludes the transfer  
  •           //if (tail == serial_tx_buffer_head) { UCSR0B &= ~(1 << UDRIE0); }  
  •           //USART_ClearITPendingBit(USART1, USART_IT_TXE);  
  •           USART1->CR1&=~(1<<7);  
  •     }     
  • }  
  •   
  • uint8_t serial_read()  
  • {  
  •   uint8_t tail = serial_rx_buffer_tail; // Temporary serial_rx_buffer_tail (to optimize for volatile)  
  •   if (serial_rx_buffer_head == tail) {  
  •     return SERIAL_NO_DATA;  
  •   } else {  
  •     uint8_t data = serial_rx_buffer[tail];  
  •     tail++;  
  •     if (tail == RX_BUFFER_SIZE) { tail = 0; }  
  •     serial_rx_buffer_tail = tail;     
  •     return data;  
  •   }  
  • }  
  •   
  • void serial_write(uint8_t data) {  
  •   // Calculate next head  
  •   uint8_t next_head = serial_tx_buffer_head + 1;  
  •   if (next_head == TX_BUFFER_SIZE) { next_head = 0; }  
  •   
  •   // Wait until there is space in the buffer  
  •   while (next_head == serial_tx_buffer_tail) {   
  •     if (sys.execute & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop.  
  •   }  
  •   
  •   // Store data and advance head  
  •   serial_tx_buffer[serial_tx_buffer_head] = data;  
  •   serial_tx_buffer_head = next_head;  
  •    
  •   // Enable Data Register Empty Interrupt to make sure tx-streaming is running  
  •   //UCSR0B |=  (1 << UDRIE0);   
  •   //发送缓冲区空中断使能,使其进入中断  
  •   USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  
  •    
  • }  
  • /*comment by zjk
  • void serial_init()
  • {
  •    
  •   // Set baud rate
  •   #if BAUD_RATE < 57600
  •     uint16_t UBRR0_value = ((F_CPU / (8L * BAUD_RATE)) - 1)/2 ;
  •     UCSR0A &= ~(1 << U2X0); // baud doubler off  - Only needed on Uno XXX
  •   #else
  •     uint16_t UBRR0_value = ((F_CPU / (4L * BAUD_RATE)) - 1)/2;
  •     UCSR0A |= (1 << U2X0);  // baud doubler on for high baud rates, i.e. 115200
  •   #endif
  •   UBRR0H = UBRR0_value >> 8;
  •   UBRR0L = UBRR0_value;
  •             
  •   // enable rx and tx
  •   UCSR0B |= 1<<RXEN0;
  •   UCSR0B |= 1<<TXEN0;
  •      
  •   // enable interrupt on complete reception of a byte
  •   UCSR0B |= 1<<RXCIE0;
  •       
  •   // defaults to 8-bit, no parity, 1 stop bit
  •    
  • }
  • void serial_write(uint8_t data) {
  •   // Calculate next head
  •   uint8_t next_head = serial_tx_buffer_head + 1;
  •   if (next_head == TX_BUFFER_SIZE) { next_head = 0; }
  •   // Wait until there is space in the buffer
  •   while (next_head == serial_tx_buffer_tail) {  
  •     if (sys.execute & EXEC_RESET) { return; } // Only check for abort to avoid an endless loop.
  •   }
  •   // Store data and advance head
  •   serial_tx_buffer[serial_tx_buffer_head] = data;
  •   serial_tx_buffer_head = next_head;
  •    
  •   // Enable Data Register Empty Interrupt to make sure tx-streaming is running
  •   UCSR0B |=  (1 << UDRIE0);  
  • }
  • // Data Register Empty Interrupt handler
  • ISR(SERIAL_UDRE)
  • {
  •   // Temporary serial_tx_buffer_tail (to optimize for volatile)
  •   uint8_t tail = serial_tx_buffer_tail;
  •    
  •   #ifdef ENABLE_XONXOFF
  •     if (flow_ctrl == SEND_XOFF) {  
  •       UDR0 = XOFF_CHAR;  
  •       flow_ctrl = XOFF_SENT;  
  •     } else if (flow_ctrl == SEND_XON) {  
  •       UDR0 = XON_CHAR;  
  •       flow_ctrl = XON_SENT;  
  •     } else
  •   #endif
  •   {  
  •     // Send a byte from the buffer   
  •     UDR0 = serial_tx_buffer[tail];
  •    
  •     // Update tail position
  •     tail++;
  •     if (tail == TX_BUFFER_SIZE) { tail = 0; }
  •    
  •     serial_tx_buffer_tail = tail;
  •   }
  •    
  •   // Turn off Data Register Empty Interrupt to stop tx-streaming if this concludes the transfer
  •   if (tail == serial_tx_buffer_head) { UCSR0B &= ~(1 << UDRIE0); }
  • }
  • uint8_t serial_read()
  • {
  •   uint8_t tail = serial_rx_buffer_tail; // Temporary serial_rx_buffer_tail (to optimize for volatile)
  •   if (serial_rx_buffer_head == tail) {
  •     return SERIAL_NO_DATA;
  •   } else {
  •     uint8_t data = serial_rx_buffer[tail];
  •     tail++;
  •     if (tail == RX_BUFFER_SIZE) { tail = 0; }
  •     serial_rx_buffer_tail = tail;
  •      
  •     #ifdef ENABLE_XONXOFF
  •       if ((get_serial_rx_buffer_count() < serial_rx_buffer_LOW) && flow_ctrl == XOFF_SENT) {  
  •         flow_ctrl = SEND_XON;
  •         UCSR0B |=  (1 << UDRIE0); // Force TX
  •       }
  •     #endif
  •      
  •     return data;
  •   }
  • }
  • ISR(SERIAL_RX)
  • {
  •   uint8_t data = UDR0;
  •   uint8_t next_head;
  •    
  •   // Pick off runtime command characters directly from the serial stream. These characters are
  •   // not passed into the buffer, but these set system state flag bits for runtime execution.
  •   switch (data) {
  •     case CMD_STATUS_REPORT: sys.execute |= EXEC_STATUS_REPORT; break; // Set as true
  •     case CMD_CYCLE_START:   sys.execute |= EXEC_CYCLE_START; break; // Set as true
  •     case CMD_FEED_HOLD:     sys.execute |= EXEC_FEED_HOLD; break; // Set as true
  •     case CMD_RESET:         mc_reset(); break; // Call motion control reset routine.
  •     default: // Write character to buffer     
  •       next_head = serial_rx_buffer_head + 1;
  •       if (next_head == RX_BUFFER_SIZE) { next_head = 0; }
  •      
  •       // Write data to buffer unless it is full.
  •       if (next_head != serial_rx_buffer_tail) {
  •         serial_rx_buffer[serial_rx_buffer_head] = data;
  •         serial_rx_buffer_head = next_head;     
  •          
  •         #ifdef ENABLE_XONXOFF
  •           if ((get_serial_rx_buffer_count() >= serial_rx_buffer_FULL) && flow_ctrl == XON_SENT) {
  •             flow_ctrl = SEND_XOFF;
  •             UCSR0B |=  (1 << UDRIE0); // Force TX
  •           }  
  •         #endif
  •          
  •       }
  •   }
  • }
  • */  
  • void serial_reset_read_buffer()   
  • {  
  •   serial_rx_buffer_tail = serial_rx_buffer_head;  
  •   
  •   #ifdef ENABLE_XONXOFF  
  •     flow_ctrl = XON_SENT;  
  •   #endif  
  • }  



     

13

主题

188

帖子

564

积分

高级技术员

发表于 2017-7-10 10:03 | 显示全部楼层 |返回版面
学习
One for all,all for one.
     

2

主题

95

帖子

298

积分

中级技术员

发表于 2017-7-17 14:08 | 显示全部楼层 |返回版面
这个跟库里的有什么不一样
各种 打杂
您需要登录后才可以回帖 登录 | 注册 手机登录

本版积分规则

关闭

热门推荐上一条 /2 下一条

分享 快速回复 返回顶部 返回列表