kinetis的RS485例程
0赞RS485是半双工通信协议,是个UART经RS485电平转换芯片后用差分信号实现远距离传输。RS485电平转换芯片有个发送使能引脚,为了获得发送权发送数据前要将该引脚设成使能状态(本例中是高电平),发送完毕再将该引脚设成低电平以释放总线。下图中第1路(黄线)是数据引脚,第2路(蓝线)是发送使能引脚。
kinetis的UART可硬件产生发送使能信号,即RTS。只需比RS232通信多设2个寄存器即可实现该功能,分别是:
1、UARTx_MODEM,其第1位TXRTSE是发送器请求发送使能位,该位为1时,当一个字符放进一个空的发送器数据缓冲区(FIFO),RTS在起始位传送之前一个bit位的时间变为有效状态(本例是高电平),在所有数据发完之后一个bit位的时间变为有效状态(本例是低电平);第2位是发送器请求发送极性(RTS引脚的极性),为1时高电平有效,为0时低电平有效。
2、UARTx_RTS引脚对应的PORT复用成UARTx_RTS。
设了上述2个寄存器,就可以自动产生上图中的第2路(蓝线)波形了。下面是完整代码(注意2行加粗斜体字):
/*
* main implementation: use this 'C' sample to create your own application
*
*/
#define GPIO_PIN_MASK 0x3C000000
#define GPIO_PIN(x) ((1<<x)&GPIO_PIN_MASK)
#include <stdio.h>
#include "derivative.h" /* include peripheral declarations */
void MCG_Init()
{
SIM_SCGC6 |= 0x20000000; //SIM_SCGC6: RTC=1
if ((RTC_CR & RTC_CR_OSCE_MASK) == 0u)//Only if the OSCILLATOR is not already enabled
{
RTC_CR &= ~0x3C00; //RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0
RTC_CR |= 0x0100; //RTC_CR: OSCE=1
RTC_CR &= ~0x0200; //RTC_CR: CLKO=0
}
//System clock initialization
SIM_CLKDIV1 = 0x01130000; //SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,OUTDIV3=1,OUTDIV4=3 Update system prescalers
SIM_SOPT2 &= ~0x00010000; //SIM_SOPT2: PLLFLLSEL=0 Select FLL as a clock source for various peripherals
SIM_SOPT1 &= ~0x00080000; //SIM_SOPT1: OSC32KSEL=0 System oscillator drives 32 kHz clock for various peripherals
// Switch to FEE Mode
SIM_SOPT2 |= 0x01;// SIM_SOPT2: MCGCLKSEL=1 0-System oscillator (OSCCLK), 1-32 kHz RTC oscillator
MCG_C2 = 0x00; // MCG_C2: ??=0,??=0,RANGE=0,HGO=0,EREFS=0,LP=0,IRCS=0
MCG_C1 = 0x02; // MCG_C1: CLKS=0,FRDIV=0,IREFS=0,IRCLKEN=1,IREFSTEN=0
MCG_C4 |= 0xE0; //MCG_C4: DMX32=1,DRST_DRS=3
MCG_C5 = 0x00; // MCG_C5: ??=0,PLLCLKEN=0,PLLSTEN=0,PRDIV=0
MCG_C6 = 0x00;// MCG_C6: LOLIE=0,PLLS=0,CME=0,VDIV=0
while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) //Check that the source of the FLL reference clock is the external reference clock.
{
}
while((MCG_S & 0x0CU) != 0x00U) // Wait until output of the FLL is selected
{
}
}
void UART_Init()
{
SIM_SCGC4 |= 1 << 10;// SIM_SCGC1: UART0=1
SIM_SCGC5 |= 1 << 9;// SIM_SCGC5: PORTA=1
PORTA_PCR17 = (3<<8) | (1<<6) ;// PORTA_PCR17: ISF=0,MUX=3 做UART,DSE=1强输出
PORTA_PCR15 = (3<<8) | (1<<6) ;// PORTA_PCR15: ISF=0,MUX=3 做UART,DSE=1强输出
PORTA_PCR14 = (3<<8) | (1<<6); // PORTA_PCR14: ISF=0,MUX=3 做UART,DSE=1强输出
UART0_C4 = 0x14; //波特率微调
UART0_BDH = (4992>>8) & 0x1F;//设波特率1200bps
UART0_BDL = 4992&0xFF;
UART0_C2 |= 1<<2;//允许接收
UART0_MODEM = (1<<2) | (1<<1);//使用RTS,高电平有效
}
void delay()
{
unsigned long int i =0;
for(i=0;i<3000000;i++)
{
asm("nop");
}
}
int main(void)
{
int tx_cnt,rx_cnt = 0;
char rcv_buf[10];
MCG_Init();
UART_Init();
printf("Hello (Kinetis) World in 'C' from MK60DX256Z derivative! \n\r");
for(;;) {
//发送
if( (UART0_S1&(1<<7)) != 0)
{
UART0_D = 0x5F;
UART0_C2 |= 1<<3;
tx_cnt++;
if(tx_cnt >= 3)
{
tx_cnt = 0;
delay();
}
}
//接收
if( (UART0_S1&(1<<5)) != 0)
{
rcv_buf[rx_cnt] = UART0_D;
rx_cnt++;
if(rx_cnt >= 10)
{
rx_cnt = 0;
}
}
}
return 0;
}