串口部分的一直只需要修改底层的串口代码就好包括串口初始化,读写函数,中断服务函数
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
- }
|
|