发一个通用的I-O模拟串口程序(适用于任何带有定时器的单片机)

合集下载

STC12C5AIO模拟I2C2014523c文件

STC12C5AIO模拟I2C2014523c文件
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
#endif
}
//**************************************
//I2C起始信号
//**************************************
/***************************************************************************
* 头文件
****************************************************************************/
Delay5us(); //延时
SCL = 0; //拉低时钟线
}
//**************************************
//I2C停止信号
//**************************************
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
* 功能: 延时
* 输入:
* 输出:
***************************************************************************/

51单片机串口通信实例

51单片机串口通信实例

51单片机串口通信实例一、原理简介51 单片机内部有一个全双工串行接口。

什么叫全双工串口呢?一般来说,只能接受或只能发送的称为单工串行;既可接收又可发送,但不能同时进行的称为半双工;能同时接收和发送的串行口称为全双工串行口。

串行通信是指数据一位一位地按顺序传送的通信方式,其突出优点是只需一根传输线,可大大降低硬件成本,适合远距离通信。

其缺点是传输速度较低。

与之前一样,首先我们来了解单片机串口相关的寄存器。

SBUF 寄存器:它是两个在物理上独立的接收、发送缓冲器,可同时发送、接收数据,可通过指令对SBUF 的读写来区别是对接收缓冲器的操作还是对发送缓冲器的操作。

从而控制外部两条独立的收发信号线RXD(P3.0)、TXD(P3.1),同时发送、接收数据,实现全双工。

串行口控制寄存器SCON(见表1) 。

表1 SCON寄存器表中各位(从左至右为从高位到低位)含义如下。

SM0 和SM1 :串行口工作方式控制位,其定义如表2 所示。

经验分享:学习单片机重要的是实践,所以开发板是很重要,给大家推荐些淘宝上信誉良好并且软硬件及小零件等、售前售后服务良好的皇冠级金钻店铺给大家,在硬件购买上少走弯路。

按住Ctrl键单击即可:慧净电子单片机(一皇冠)【天津商盟】天津锐志(电子)单片机经营部(两皇冠)金沙滩工作室(5钻)深圳育松电子元件,模块,传感器,批发部:淘宝最全最平价(5皇冠)志宏电子(4钻)表2 串行口工作方式控制位其中,fOSC 为单片机的时钟频率;波特率指串行口每秒钟发送(或接收)的位数。

SM2 :多机通信控制位。

该仅用于方式2 和方式3 的多机通信。

其中发送机SM2 = 1(需要程序控制设置)。

接收机的串行口工作于方式2 或3,SM2=1 时,只有当接收到第9 位数据(RB8)为1 时,才把接收到的前8 位数据送入SBUF,且置位RI 发出中断申请引发串行接收中断,否则会将接受到的数据放弃。

当SM2=0 时,就不管第位数据是0 还是1,都将数据送入SBUF,并置位RI 发出中断申请。

51单片机模拟spi串行接口程序

51单片机模拟spi串行接口程序
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;
DataI=0; // write
if(val&0x80) DataI=1;
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbiபைடு நூலகம் DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
val<<=1;
CLK=1;
if(DataO)val|=1; // read
}
CLK=0;
return val;
}
sbit CLK= P1^5;
sbit DataI=P1^7;
sbit DataO=P1^6;
#define SD_Disable() CS=1 //片选关
#define SD_Enable() CS=0 //片选开
unsigned char SPI_TransferByte(unsigned char val)
{
unsigned char BitCounter;
for(BitCounter=8; BiCounter!=0; BitCounter--)
{ CLK=0;

如何使用单片机的单个IO口模拟串口UART输出

如何使用单片机的单个IO口模拟串口UART输出
if(பைடு நூலகம்at & BIT(i)) {
IO_UART_TX_H(); } else {
IO_UART_TX_L(); asm("l.nop");//延时一个机器周期 } delay_one_bit_tx(); } IO_UART_TX_H();//发送结束位 delay_one_bit_tx(); }
1
V1.0
模拟的串口协议如下:
起始位 1 位 数据位 8 位 停止位 1 位 校验位 无
参考的代码如下:
void io_uart_send_byte(unsigned char dat) {
Unsigned char i ; IO_UART_TX_L();//拉低作为起始 delay_one_bit_tx();//按照需要的波特率来延时 for(i = 0 ; i< 8 ; i++) {
普通 MCU 模拟串口发送说明
相关说明:
(1)、模拟 115200 波特率,信号跳变的时间为 8.68uS = 1 / 115200 (2)、模拟 9600 波特率,信号跳变的时间为 104.1uS = 1 / 9600 (3)、串口的波特率越高,所需要的时间越短,相对稳定性越差,建议采用 9600 波特率。 (4)、串口的发射模拟相对比较容易,接收比较困难。下面就串口的 IO 模拟发射做说明 (5)、我们的串口允许的时钟误差最多 3%。所以用户请严格的控制时间误差在这个范围。

运用4个普通IO口模拟SPI程序等

运用4个普通IO口模拟SPI程序等
SIG--------- PORTB.0 双项输入 Din--------- PORTB.2 单项输出 Dout-------- PORTB.3 双项输入 SCLK-------- PORTB.4 单项输出 CS---------- PORTB.5 单项输出 SEL--------- PORTB.6 单项输出 RESET------- PORTB.1 单项输出 #define SET1302_RST PORTB|=(1<<7) #define CLR1302_RST PORTB&=~(1<<7) ************************************************************* ************************/ #define ATT_SIG PINB.0 #define ATT_Din PORTB.2 #define ATT_Dout PINB.3 #define ATT_SCLK PORTB.4
运用 4 个普通 I/O 口模拟 SPI 程序源代码
/******************************************************************** 函 数 名:uchar SpiReadWrite(uchar dat) 功 能:SPI 发送接收一个数据 说 明: 调 用: 入口参数: 出口参数: ***********************************************************************/ uchar SpiReadWrite(uchar dat) { uchar i,temp; temp=0; SCK=0; _nop_(); for(i=0;i<8;i++) { if(dat & 0x80) { MOSI=1; }

简单好用的stc12c5a串口2发送程序!

简单好用的stc12c5a串口2发送程序!

//功能:stc12c5a串口2发送程序,发送0--9,晶振频率11.0592MHz,串行口工作于方式1,波特率为9600#ifndef __STC12C5A60S2_H__#define __STC12C5A60S2_H__//--------------------------------------------------------------------------------//新一代 1T 8051系列单片机内核特殊功能寄存器 C51 Core SFRs// 7 6 5 4 3 21 0 Reset Valuesfr ACC = 0xE0; //Accumulator 0000,0000sfr B = 0xF0; //B Register 0000,0000sfr PSW = 0xD0; //Program Status Word CY AC F0 RS1 RS0 OVF1 P 0000,0000//-----------------------------------sbit CY = PSW^7;sbit AC = PSW^6;sbit F0 = PSW^5;sbit RS1 = PSW^4;sbit RS0 = PSW^3;sbit OV = PSW^2;sbit P = PSW^0;//-----------------------------------sfr SP = 0x81; //Stack Pointer 0000,0111sfr DPL = 0x82; //Data Pointer Low Byte 0000,0000sfr DPH = 0x83; //Data Pointer High Byte 0000,0000//--------------------------------------------------------------------------------//新一代 1T 8051系列单片机系统管理特殊功能寄存器// 7 6 5 4 3 21 0 Reset Valuesfr PCON = 0x87; //Power Control SMOD SMOD0 LVDF POF GF1 GF0 PDIDL 0001,0000// 7 6 5 4 3 21 0 Reset Valuesfr AUXR = 0x8E; //Auxiliary Register T0x12 T1x12 UART_M0x6 BRTR S2SMOD BRTx12 EXTRAM S1BRS 0000,0000//-----------------------------------sfr AUXR1 = 0xA2; //Auxiliary Register 1 - PCA_P4 SPI_P4 S2_P4 GF2 ADRJ -DPS 0000,0000/*PCA_P4:0, 缺省PCA 在P1 口1,PCA/PWM 从P1 口切换到P4 口: ECI 从P1.2 切换到P4.1 口,PCA0/PWM0 从P1.3 切换到P4.2 口PCA1/PWM1 从P1.4 切换到P4.3 口SPI_P4:0, 缺省SPI 在P1 口1,SPI 从P1 口切换到P4 口: SPICLK 从P1.7 切换到P4.3 口MISO 从P1.6 切换到P4.2 口MOSI 从P1.5 切换到P4.1 口SS 从P1.4 切换到P4.0 口S2_P4:0, 缺省UART2 在P1 口1,UART2 从P1 口切换到P4 口: TxD2 从P1.3 切换到P4.3 口RxD2 从P1.2 切换到P4.2 口GF2: 通用标志位ADRJ:0, 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器1,10 位A/D 转换结果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器DPS: 0, 使用缺省数据指针DPTR01,使用另一个数据指针DPTR1*///-----------------------------------sfr WAKE_CLKO = 0x8F; //附加的 SFR WAK1_CLKO/*7 6 5 4 3 2 1 0 Reset ValuePCAWAKEUP RXD_PIN_IE T1_PIN_IE T0_PIN_IE LVD_WAKE _ T1CLKO T0CLKO 0000,0000Bb7 - PCAWAKEUP : PCA 中断可唤醒 powerdown。

51单片机GPIO口模拟串口通信

51单片机GPIO口模拟串口通信

51单片机GPIO口模拟串口通信随着单片机的使用日益频繁,用其作前置机进行采集和通信也常见于各种应用,一般是利用前置机采集各种终端数据后进行处理、存储,再主动或被动上报给管理站。

这种情况下下,采集会需要一个串口,上报又需要另一个串口,这就要求单片机具有双串口的功能,但我们知道一般的51 系列只提供一个串口,那么另一个串口只能靠程序模拟。

本文所说的模拟串口,就是利用51的两个输入输出引脚P1.0 和P1.1,置1 或0 分别代表高低电平,也就是串口通信中所说的位,如起始位用低电平,则将其置0,停止位为高电平,则将其置1,各种数据位和校验位则根据情况置1 或置0。

以11.0592MHz 的晶振为例,通过定时计数器0 产生中断信号来模拟串口电平,下面附上具体源代码。

[cpp]view plaincopy/*Fuction:使用51 单片机GPIO 口模拟串口通信,通过定时计数器0 来产生中断信号SoftwareDesigner:Jason*/#includesbitP1_0=P1;sbitP1_1=P1;#de fine RXD P1_0#de fineTXDP1_1unsignedcharflag;voidinit();voidsend_byte(unsignedchar);unsignedchar rec_byte();voidwait_int();//将从PC 机串口接收到的数据原封不动回传给PC 机voidmain(){unsignedchartemp;init();while(1){if(RI==1){RI=0;temp=rec_byte();send_byte(temp);while(!TI);TI=0;}}}//端口及中断初始化voidinit(){TMOD=0x02;//定时器0,方式2TH0=0xfd;//波特率9600TL0=TH0;TR0=0;//在发送或接收时打开ET0=1;//允许定时器0 中断EA=1;//允许所有中断}//通过串口发送一个字节数据voidsend_byte(unsignedchardat){unsignedchari=8;TR0=1;//开启T0 中断TXD=0;//发送起始位0wait_int();while(i--)//发送8 位数据{TXD=(bit)(dat&0x01);wait_int();dat=dat>>1;}TXD=1;//发送停止位1wait_int();TR0=0;//关闭T0 中断}//通过串口。

51单片机串口工作方式0和1

51单片机串口工作方式0和1

ACALL DELAY
CLR TI
; 手动清中断标志
RR A ; 循环位移
; 80H、40H、20H、10H、08H …
CLR P1.0
; CD4094 输出并口关闭
MOV SBUF,A ; 数据传出,产生中断
RETI
END
注: 延时子程序 DELAY 未给出
2021/5/15
方式 0 用于扩展并行 I/O口
=
/32
9600bps 1200bps
=
/12/计次/16
计1次 计3次 计3次 计6次 计12次 计24次
9.6kbit/s 实际10.416 = 6MHz/12/计次/16 1
0
2
FDH
1.2kbit/s 实际1.302 = 6MHz/12/计次/32 0
0
2
F4H
时钟振荡频率为6MHz或12 MHz时,产生的比特率偏差较大,
写入SBUF后自动开始发 送
2021/5/15
图5-1
请求中断
CPU响应中断后:CLR TI
5.2 用AT89C51的串行口扩展并行口
5.2.2 用74LS164扩展并行输出口
74LS164:8位串入并出移位寄存器。
图是利用74LS164扩展二个8位并行输出口的接口电路。

每当新数据写入SBUF,即把SBUF中的8位数据以串行移
• 数据区
发送数据区首址 20H,接收数据区首址 40H
• 主频选用
fosc = 6MHz
• T1 设置
,同时RI=0)时,串行口即开始接收数据。RXD为数据输入端
,TXD为移位脉冲信号输出端,也以fosc/12的固定比特率,
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void _putchar( char ch ) { while ( flag_tx_ready ); user_tx_buffer = ch;
// invoke_UART_transmit timer_tx_ctr = 3; bits_left_in_tx = tx_num_of_bits; internal_tx_buffer = (user_tx_buffer<<1) | 0x200; flag_tx_ready = TRUE; }
3 欢迎光临中国最大的电子工程师应用网站 网址:
电子下载站 资料版权归合法所有者所有 严禁用于商业用途
// Test for Start Bit if ( start_bit==0 ) { flag_rx_ready = TRUE; internal_rx_buffer = 0; timer_rx_ctr = 4; bits_left_in_rx = rx_num_of_bits; rx_mask = 1; } } else // rx_busy { if ( --timer_rx_ctr<=0 ) { // rcv timer_rx_ctr = 3; flag_in = get_rx_pin_status(); if ( flag_in ) {
char _getchar( void ) { char ch;
do { while ( qout==qin ) { idle(); } ch = inbuf[qout] & 0xFF; if ( ++qout>=IN_BUF_SIZE ) { qout = 0; } } while ( ch==0x0A || ch==0xC2 ); return( ch ); }
static char flag_rx_waiting_for_stop_bit; static char flag_rx_off; static char rx_mask; static char flag_rx_ready; static char flag_tx_ready; static char timer_rx_ctr; static char timer_tx_ctr; static char bits_left_in_rx; static char bits_left_in_tx; static char rx_num_of_bits; static char tx_num_of_bits; static char internal_rx_buffer; static char internal_tx_buffer; static char user_tx_buffer;
欢迎光临中国最大的电子工程师应用网站 网址:
电子下载站 资料版权归合法所有者所有 严禁用于商业用途
// Turns on the receive function. // 5. void turn_rx_off( void ) // Turns off the receive function. // 6. void putchar( char ) // Writes a character to the serial port.
电子下载站 资料版权归合法所有者所有 严禁用于商业用途
发一个通用的 I/O 模拟串口程序(适用于任何带有定时器的单片机)
// UART.C // // Generic software uart written in C, requiring a timer set to 3 times // the baud rate, and two software read/write pins for the receive and // transmit functions. // // * Received characters are buffered // * putchar(), getchar(), kbhit() and flush_input_buffer() are available // * There is a facility for background processing while waiting for input // // Colin Gittins, Software Engineer, Halliburton Energy Services // // The baud rate can be configured by changing the BAUD_RATE macro as // follows: // // #define BAUD_RATE 19200.0 // // The function init_uart() must be called before any comms can take place // // Interface routines required: // 1. get_rx_pin_status() // Returns 0 or 1 dependent on whether the receive pin is high or low. // 2. set_tx_pin_high() // Sets the transmit pin to the high state. // 3. set_tx_pin_low() // Sets the transmit pin to the low state. // 4. idle() // Background functions to execute while waiting for input. // 5. timer_set( BAUD_RATE ) // Sets the timer to 3 times the baud rate. // 6. set_timer_interrupt( timer_isr ) // Enables the timer interrupt. // // Functions provided: // 1. void flush_input_buffer( void ) // Clears the contents of the input buffer. // 2. char kbhit( void ) // Tests whether an input character has been received. // 3. char getchar( void ) // Reads a character from the input buffer, waiting if necessary. // 4. void turn_rx_on( void )
void flush_input_buffer( void ) {
5 欢迎光临中国最大的电子工程师应用网站 网址:
电子下载站 资料版权归合法所有者所有 严禁用于商业用途
qin = 0; qout = 0; } char kbhit( void ) { return( qin!=qout ); } void turn_rx_on( void ) { flag_rx_off = FALSE; } void turn_rx_off( void ) { flag_rx_off = TRUE; }
#include <stdio.h>
#define BAUD_RATE 19200.0
#define IN_BUF_SIZE 256
#define TRUE 1 #define FALSE 0
static unsigned char inbuf[IN_BUF_SIZE]; static unsigned char qin = 0; static unsigned char qout = 0;
4 欢迎光临中国最大的电子工程师应用网 网址:电子下载站 资料版权归合法所有者所有 严禁用于商业用途
rx_num_of_bits = 10; tx_num_of_bits = 10;
set_tx_pin_low();
timer_set( BAUD_RATE ); set_timer_interrupt( timer_isr ); // Enable timer interrupt }
void timer_isr(void) { char mask, start_bit, flag_in;
// Transmitter Section if ( flag_tx_ready ) { if ( --timer_tx_ctr<=0 ) {
2 欢迎光临中国最大的电子工程师应用网站 网址:
电子下载站 资料版权归合法所有者所有 严禁用于商业用途
mask = internal_tx_buffer&1; internal_tx_buffer >>= 1; if ( mask ) { set_tx_pin_high(); } else { set_tx_pin_low(); } timer_tx_ctr = 3; if ( --bits_left_in_tx<=0 ) { flag_tx_ready = FALSE; } } } // Receiver Section if ( flag_rx_off==FALSE ) { if ( flag_rx_waiting_for_stop_bit ) { if ( --timer_rx_ctr<=0 ) { flag_rx_waiting_for_stop_bit = FALSE; flag_rx_ready = FALSE; internal_rx_buffer &= 0xFF; if ( internal_rx_buffer!=0xC2 ) { inbuf[qin] = internal_rx_buffer; if ( ++qin>=IN_BUF_SIZE ) { qin = 0; } } } } else // rx_test_busy { if ( flag_rx_ready==FALSE ) { start_bit = get_rx_pin_status();
相关文档
最新文档