📄 serial.c
字号:
//-----------------------------------------------------------------------------
// Contents: main module of a simple firmware
//
// Copyright: Inventec Electronics(Tianjin) Co., Ltd.
// $Archive: serial.c
// $Date: 2007-08-06
// $Revision: 1.00
//
//-----------------------------------------------------------------------------
// Copyright 2006, xsh.han@itc.inventec
//-----------------------------------------------------------------------------
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "fx2.h"
#include "fx2regs.h"
#include "absacc.h"
#include "serial.h"
//------------------------------------------------------------------------------
//for serial baudspeed,
//CLKOUT = 12Mhz,24Mhz,48Mhz
//baudspeed = 9600,19200,28800,38400,57600
BYTE xdata timer1Cnt[4][5] =
{
{0xEC,0xF6,0xF9,0xFB,0xFD},
{0xD9,0xEC,0xF3,0xF6,0xF9},
{0xB2,0xD9,0xE6,0xEC,0xF3},
{0x00,0x00,0x00,0x00,0x00},
};
BYTE xdata timer2Cnt[4][5] =
{
{0xD9,0xEC,0xF3,0xF6,0xF9},
{0xB2,0xD9,0xE6,0xEC,0xF3},
{0x64,0xB2,0xCC,0xD9,0xE6},
{0x00,0x00,0x00,0x00,0x00},
};
//global varable
//for printf format to string
#ifndef __STD_PRINTF__
BYTE xdata prf_buff[COMM_BUFF_LEN];
#endif
//================================================================================
#ifndef __UNUSE_SERIAL0__
//================================================================================
//for serial0 receive and send
BYTE xdata serial0_buff[COMM_BUFF_LEN];
BYTE xdata serial0_read_pos = 0;
BYTE xdata serial0_write_pos = 0;
bit serial0_full_flag = 0;
//================================================================================
#endif
//================================================================================
//================================================================================
#ifdef __USE_SERIAL1__
//================================================================================
//for serial0 receive and send
BYTE xdata serial1_buff[COMM_BUFF_LEN];
BYTE xdata serial1_read_pos = 0;
BYTE xdata serial1_write_pos = 0;
bit serial1_full_flag = 0;
//================================================================================
#endif
//================================================================================
//--------------------------------------------------------------------------------
//function: serial port setting
//input: baudspeed- baud speed, 9600,19200,28800,38400,57600
// databits = 8,stopbits = 1,parity = N
//return: 0 - succeed, -1 - failed
//--------------------------------------------------------------------------------
//***** use timer1/2 as baud rate generator *****
//***** baurd as 57600 have bad data in ot out *****
//***** the counter is CLKOUT=12MHZ *****
//--------------------------------------------------------------------------------
int serial_init(WORD baudspeed,WORD timer1)
{
WORD clk_spd;
clk_spd = (CPUCS & bmCLKSPD)>>3;
if (timer1) {
PCON |= 0x80; /* serial port0 baud double enable*/
SCON0 = 0x70; /* serial port0 mode=1,8bits,1start,1stop,noneparity*/
TMOD = 0x20; /* TMOD: timer 1, mode 2, 8-bit reload */
TCON = 0x40; /* timer1 as baud rate generator*/
CKCON |=0x10;
switch(baudspeed) {
case 57600: TH1 = timer1Cnt[clk_spd][4]; break;
case 38400: TH1 = timer1Cnt[clk_spd][3]; break;
case 28800: TH1 = timer1Cnt[clk_spd][2]; break;
case 19200: TH1 = timer1Cnt[clk_spd][1]; break;
case 9600: TH1 = timer1Cnt[clk_spd][0]; break;
default: return -1;
}
//TI = 1;
//RI = 0;
ENABLE_SERIAL0_IRQ; //Enable Serial Interrupt
#ifdef __USE_SERIAL1__
EICON |= 0x80; /* serial port1 baud double enable*/
SCON1 = 0x70; /* serial port1 mode=1,8bits,1start,1stop,noneparity*/
ENABLE_SERIAL1_IRQ; //Enable Serial Interrupt
#endif
}else{
//PCON = PCON&0x7F; /* serial port0 baud double disable*/
SCON0 = 0x70; /* serial port0 mode=1,8bits,1start,1stop,noneparity*/
T2CON = 0x34; /* timer2 as baud rate generator*/
TH2 = 0x0;
TL2 = 0x0;
//CKCON |=0x20;
//timerCounter = 65536 - CLKOUT/32/baudspeed.
switch(baudspeed) {
case 57600: RCAP2H = 0xFF; RCAP2L = timer2Cnt[clk_spd][4]; break;
case 38400: RCAP2H = 0xFF; RCAP2L = timer2Cnt[clk_spd][3]; break;
case 28800: RCAP2H = 0xFF; RCAP2L = timer2Cnt[clk_spd][2]; break;
case 19200: RCAP2H = 0xFF; RCAP2L = timer2Cnt[clk_spd][1]; break;
case 9600: RCAP2H = 0xFF; RCAP2L = timer2Cnt[clk_spd][0]; break;
default: return -1;
}
//TI = 1;
//RI = 0;
ENABLE_SERIAL0_IRQ; //Enable Serial Interrupt
}
//----------------------
//Enable 8051 interrupts
//EZUSB_InitI2C() have do it
//----------------------
EA = 1;
return 0;
}
//================================================================================
#ifndef __UNUSE_SERIAL0__
//================================================================================
//--------------------------------------------------------------------------------
//function: get input from serial , no wait
//param:
// ch[out]: data recieved if have it
//return:
// BOOL: 0 - succeed, -1 - failed
//--------------------------------------------------------------------------------
BOOL serial0_get_char(char *c)
{
if (serial0_read_pos != serial0_write_pos) {
*c = serial0_buff[serial0_read_pos];
serial0_read_pos = (serial0_read_pos + 1) % COMM_BUFF_LEN;
serial0_full_flag = 0;
return 1;
}
return 0;
}
//--------------------------------------------------------------------------------
//从串口读取一个字符串
//param:
// str[in] : data of read
// strlen[in] : 为该字符串长度
//return:
// length of read
//--------------------------------------------------------------------------------
int serial0_get_string(unsigned char *str,unsigned int strlen)
{
int i = 0;
while(serial0_get_char(str+i) && i<COMM_BUFF_LEN && i<strlen) {
i++;
}
return (i);
}
//--------------------------------------------------------------------------------
//向串口发送一个字符
//param:
// ch[in]: data for sendout
//return:
// none
//--------------------------------------------------------------------------------
void serial0_put_char(unsigned char ch)
{
SBUF0 = ch;
while(TI == 0);
TI = 0;
}
//--------------------------------------------------------------------------------
//向串口发送一个字符串
//param:
// str[in] : data of send
// strlen[in] : 为该字符串长度
//return:
// none
//--------------------------------------------------------------------------------
void serial0_put_string(unsigned char *str,unsigned int strlen)
{
int i = 0;
do {
serial0_put_char(*(str + i));
i++;
} while(i < strlen);
}
//--------------------------------------------------------------------------------
//调用自己的串口函数发送数据,使用printf形式。
//param:
// fmt[in] : format string
// ...[in] : data
//return:
// int[out]: length
//--------------------------------------------------------------------------------
#ifndef __STD_PRINTF__
int serial0_printf(const char *fmt, ...)
{
int ret;
va_list arg_ptr;
va_start(arg_ptr, fmt); /* format string */
vsprintf(prf_buff, fmt, arg_ptr);
va_end(arg_ptr);
//out to serial
ret = strlen(prf_buff);
serial0_put_string(prf_buff,ret);
return(ret);
}
#endif
//--------------------------------------------------------------------------------
//function: serial interrupt service
//--------------------------------------------------------------------------------
void serial0_isr() interrupt COM0_VECT //using 3
{
//process receive date
if (RI){
RI = 0;
serial0_buff[serial0_write_pos] = SBUF0;
serial0_write_pos = (serial0_write_pos + 1) % COMM_BUFF_LEN;
if (serial0_write_pos == serial0_read_pos){
serial0_full_flag = 1;
}
}
//clear send intr
//if (TI){
// TI = 0;
//}
}
//================================================================================
#endif
//================================================================================
//================================================================================
#ifdef __USE_SERIAL1__
//================================================================================
//--------------------------------------------------------------------------------
//function: get input from serial , no wait
//param:
// ch[out]: data recieved if have it
//return:
// BOOL: 0 - succeed, -1 - failed
//--------------------------------------------------------------------------------
BOOL serial1_get_char(char *c)
{
if (serial1_read_pos != serial1_write_pos) {
*c = serial1_buff[serial1_read_pos];
serial1_read_pos = (serial1_read_pos + 1)%COMM_BUFF_LEN;
serial1_full_flag = 0;
return 1;
}
return 0;
}
//--------------------------------------------------------------------------------
//从串口读取一个字符串
//param:
// str[in] : data of read
// strlen[in] : 为该字符串长度
//return:
// length of read
//--------------------------------------------------------------------------------
int serial1_get_string(unsigned char *str,unsigned int strlen)
{
int i = 0;
while(serial1_get_char(str+i) && i<COMM_BUFF_LEN && i<strlen) {
i++;
}
return (i);
}
//--------------------------------------------------------------------------------
//向串口发送一个字符
//param:
// ch[in]: data for sendout
//return:
// none
//--------------------------------------------------------------------------------
void serial1_put_char(unsigned char ch)
{
SBUF1 = ch;
while(TI1 == 0);
TI1 = 0;
}
//--------------------------------------------------------------------------------
//向串口发送一个字符串
//param:
// str[in] : data of send
// strlen[in] : 为该字符串长度
//return:
// none
//--------------------------------------------------------------------------------
void serial1_put_string(unsigned char *str,unsigned int strlen)
{
unsigned int i = 0;
do {
serial1_put_char(*(str + i));
i++;
} while(i < strlen);
}
//--------------------------------------------------------------------------------
//调用自己的串口函数发送数据,使用printf形式。
//param:
// fmt[in] : format string
// ...[in] : data
//return:
// int[out]: length
//--------------------------------------------------------------------------------
#ifndef __STD_PRINTF__
int serial1_printf(const char *fmt, ...)
{
int ret;
va_list arg_ptr;
va_start(arg_ptr, fmt); /* format string */
vsprintf(prf_buff, fmt, arg_ptr);
va_end(arg_ptr);
//out to serial
ret = strlen(prf_buff);
serial1_put_string(prf_buff,ret);
return(ret);
}
#endif
//--------------------------------------------------------------------------------
//function: serial interrupt service
//--------------------------------------------------------------------------------
void serial1_isr() interrupt COM1_VECT
{
//process receive date
if (RI1){
RI1 = 0;
serial1_buff[serial1_write_pos] = SBUF1;
serial1_write_pos = (serial1_write_pos + 1) % COMM_BUFF_LEN;
if (serial1_write_pos == serial1_read_pos){
serial1_full_flag = 1;
}
}
}
//================================================================================
#endif
//================================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -