📄 rs485.c
字号:
/*
* File: rs485.c
* Purpose: Provide common ColdFire rs485 routines for serial IO
*
* Notes: 99% of this code stolen/borrowed from the uart.c and uart.h
* examples.
* author: michael.chen
* e-mail: mingzhixx@gmail.com
*/
#include "common.h"
#include "rs485.h"
#define MCF_GPIO_PTD_PAR_PWM7 (0x08)
#define MCF_GPIO_DDR_PWM7 (0x08)
#define MCF_GPIO_OUT_SET (0x08)
/*
* To do -- enhance to a more complete driver with interrupts, dma, etc.
*/
/********************************************************************/
/*
* Initialize the rs485 for 8N1 operation, interrupts disabled, and
* no hardware flow-control
*
* Parameters:
* uartch UART channel to initialize
* sysclk UART System Clock (in KHz)
* baud UART baud rate
* settings Initialization parameters
*
*
*Note : firstly we should set RXD1 and TXD1 .at hhcf521x-r1-kirin board we use PWM7 to control RS485's ~RE and DE.
* here we initialize the rs485 under receive mode.
*/
void
rs485_init (int uartch, int sysclk, int baud, int settings)
{
register uint16 ubgs;
/*
*IPSBAR+005A:PUBPAR
* 7 6 5 4 3 2 1 0
*| PAR3 | PAR2 | PAR1| PAR0|
*RESET0 0 0 0 0 0 0 0
* GPIO GPIO RXD1 TXD1
* 0 0 0 0 0 1 0 1
*/
MCF_GPIO_PUBPAR |= 0x05; //set RXD1 and TXD1
/*
* Reset Transmitter
*/
MCF_UART_UCR(uartch) = MCF_UART_UCR_RESET_TX;
/*
* Reset Receiver
*/
MCF_UART_UCR(uartch) = MCF_UART_UCR_RESET_RX;
/*
* Reset Mode Register
*/
MCF_UART_UCR(uartch) = MCF_UART_UCR_RESET_MR;
/*
* No parity, 8-bits per character
*/
MCF_UART_UMR(uartch) = (0
| MCF_UART_UMR_PM_NONE
| MCF_UART_UMR_BC_8);
/*
* No echo or loopback, 1 stop bit
*/
MCF_UART_UMR(uartch) = (0
| MCF_UART_UMR_CM_NORMAL
| MCF_UART_UMR_SB_STOP_BITS_1);
/*
* Set Rx and Tx baud by timer
*/
MCF_UART_UCSR(uartch) = (0
| MCF_UART_UCSR_RCS_SYS_CLK
| MCF_UART_UCSR_TCS_SYS_CLK);
/*
* Mask all UART interrupts
*/
MCF_UART_UIMR(uartch) = 0;
/*
* Calculate baud settings
*/
ubgs = (uint16)((sysclk*1000)/(baud * 32));
MCF_UART_UBG1(uartch) = (uint8)((ubgs & 0xFF00) >> 8);
MCF_UART_UBG2(uartch) = (uint8)(ubgs & 0x00FF);
/*
* set PWM7 as GPIO, clr PWM7 port,let rs485 into recieve mode
*/
MCF_GPIO_PTDPAR &= ~MCF_GPIO_PTD_PAR_PWM7; //set pwm7 as GPIO
MCF_GPIO_DDRTD |= MCF_GPIO_DDR_PWM7; //PWM7 is GPIO output
MCF_GPIO_PORTTD &= ~MCF_GPIO_OUT_SET; //PWM7 output have been clear
/*
* Enable receiver and transmitter
*/
MCF_UART_UCR(uartch) = (0
| MCF_UART_UCR_TX_ENABLED
| MCF_UART_UCR_RX_ENABLED);
}
/********************************************************************/
/*
* Wait for a character to be received on the specified UART
*
* Return Values:
* the received character
*/
char
rs485_getchar (int channel)
{
/* Wait until character has been received */
while (!(MCF_UART_USR(channel) & MCF_UART_USR_RXRDY))
;
return MCF_UART_URB(channel);
}
/********************************************************************/
/*
* Wait for space in the UART Tx FIFO and then send a character
* finally make UART into receive mode.
*/
void
rs485_putchar (int channel, char ch)
{
char i;
/*set transfer mode*/
MCF_GPIO_PORTTD |= MCF_GPIO_OUT_SET;
/* Wait until space is available in the FIFO */
while (!(MCF_UART_USR(channel) & MCF_UART_USR_TXRDY))
;
/* Send the character */
MCF_UART_UTB(channel) = (uint8)ch;
/*set recieve mode*/
MCF_GPIO_PORTTD &= ~MCF_GPIO_OUT_SET;
}
/********************************************************************/
/*
* Check to see if a character has been received
*
* Return values:
* 0 No character received
* 1 Character has been received
*/
int
rs485_getchar_present (int channel)
{
return (MCF_UART_USR(channel) & MCF_UART_USR_RXRDY);
}
/********************************************************************/
/*******************************************************************/
/*
*
*the task of test the rs485 module
*
*function: sent from "a" to "z" into 485 module.and then wait for
* the 485's input for output 26 characters again.
*
*
*
*
*
*
*/
OS_STK AppTaskRs485Stk[256]; // The TaskStack for the rs485 Task
void AppTaskRs485 (void * pdata)
{
char i = 0;
rs485_init(1,SYS_CLK_KHZ,115200,NULL);
while(1)
{
printf("\nstart to output 26 charater in 485 port!\n");
for(i=0;i<26;i++)
{
rs485_putchar (1,'a'+i); //output 26 charaters
}
/*
* Special chars like
* '\n' or '\t' are normally converted to the appropriate
* character by the __compiler__. Thus, no need for this
* routine to account for the '\' character.
*/
/*
* This needs to be replaced with something like
* 'out_char()' or call an OS routine.
*/
#ifndef UNIX_DEBUG //out '\n'
rs485_putchar (1,0x0D /* CR */);
rs485_putchar (1,0x0A /* LF */);
#else
rs485_putchar (1,'\n');
#endif
printf("\ninput a charater in 485 port! let 485 port these 26 charaters again!\n");
i = rs485_getchar (1); //wait for rs485 intput
#ifndef UNIX_DEBUG //out '\n'
rs485_putchar (1,0x0D /* CR */);
rs485_putchar (1,0x0A /* LF */);
#else
rs485_putchar (1,'\n');
#endif
OSTimeDly(50);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -