STM8单片机串口发送引脚和接收引脚分开使用
在使用STM8S003单片机时,需要用到ADC采样功能,STM8S003总共有5个ADC采样口,但是其中两个采样口是和串口复用的,如果当ADC口用,就不能用串口,如果当串口用,就不能用ADC口。
通过芯片管脚的原理图可以看到PD5口可以当作模拟采样第5通道使用,也可以用当做串口发送口使用。PD6口可以当做模拟采样第6通道使用,也可以当做串口接收口使用。
在项目中需要将串口当做AD口使用,但是也需要串口向外发送监控数据。AD功能和串口功能需要同时使用,于是想到,串口只用到了发送引脚,那么能不能将串口的接收引脚当做AD功能用。这样PD5口作为串口发送引脚使用,PD6口作为模拟采样第6通道使用。
先写一个简单的测试程序测试一下这种是否可行。
首先将串口初始化程序中的,接收引脚和接收功能屏蔽掉。
将串口的接收引脚和接收功能屏蔽掉,串口只使用发送引脚和发送功能。
完整串口初始化代码如下:
#include "uart.h"
#include "main.h"//重新定向putchar函数,使支持printf函数
int putchar( int ch )
{while( !( UART1_SR & 0X80 ) ); //循环发送,直到发送完毕UART1_DR = ( u8 ) ch;return ch;
}
//串口只用发送口,不用接收口
void Uart1_IO_Init( void )
{PD_DDR |= ( 1 << 5 ); //输出模式 TXDPD_CR1 |= ( 1 << 5 ); //推挽输出//PD_DDR &= ~( 1 << 6 ); //输入模式 RXD//PD_CR1 &= ~( 1 << 6 ); //浮空输入
}//波特率最大可以设置为38400
void Uart1_Init( unsigned int baudrate )
{unsigned int baud;baud = 16000000 / baudrate;Uart1_IO_Init();UART1_CR1 = 0; //禁止发送和接收UART1_CR2 = 0; //8 bitUART1_CR3 = 0; //1 stopUART1_BRR2 = ( unsigned char )( ( baud & 0xf000 ) >> 8 ) | ( ( unsigned char )( baud & 0x000f ) );UART1_BRR1 = ( ( unsigned char )( ( baud & 0x0ff0 ) >> 4 ) );
// UART1_CR2_bit.REN = 1; //接收使能UART1_CR2_bit.TEN = 1; //发送使能UART1_CR2_bit.RIEN = 1; //接收中断使能
}//阻塞式发送函数
void SendChar( unsigned char dat )
{while( ( UART1_SR & 0x80 ) == 0x00 ); //发送数据寄存器空UART1_DR = dat;
}
//发送字符串
void SendString( unsigned char* s )
{while( 0 != *s ){SendChar( *s );s++;}
}//接收中断函数 中断号18
#pragma vector = 20 // IAR中的中断号,要在STVD中的中断号上加2
__interrupt void UART1_Handle( void )
{unsigned char res = 0;res = UART1_DR;UART1_SR &= ~( 1 << 5 ); //RXNE 清零}
下来将PD6引脚设置为ADC采样功能,完整初始化代码如下:
#include "adc.h"
#include "main.h"u16 DATAH = 0; //ADC转换值高8位
u16 DATAL = 0; //ADC转换值低8位
_Bool ADC_flag = 0; //ADC转换成功标志//AD通道引脚初始化
void ADC_GPIO_Init( void )
{PD_DDR &= ~( 1 << 6 ); //PD6 设置为输入 AIN6 PD_CR1 &= ~( 1 << 6 ); //PD6 设置为悬空输入}void ADC_CH_Init( u8 ch )
{char l = 0;ADC_CR1 = 0x00; //fADC = fMASTER/2, 8Mhz 单次转换,禁止转换ADC_CSR = ch + 1; //控制状态寄存器 选择要 AD输入通道 如:PD2(AIN3)ADC_CR2 = 0x00; //默认左对齐 读数据时先读高在读低ADC_TDRL = ( 1 << ( ch + 1 ) ); //禁止相应通道 施密特触发功能 1左移ch+1位ADC_CR1 |= 0x01; //使能ADC并开始转换ADC_CSR |= 0x20; //EOCIE 使能转换结束中断 EOC中断使能for( l = 0; l < 100; l++ ); //延时,保证ADC模块的上电完成 至少7usADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 使能ADC 并开始转换
}//采集PD6电压值 AIN6
u16 ReadVol_CH6( void )
{u16 voltage = 0;ADC_CH_Init( 5 );if( ADC_flag ){ADC_flag = 0;voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据 0--1024//ADC_CR1 = ADC_CR1 | 0x01; //再次将CR1寄存器的最低位置1 启动下一次转换};return voltage;
}//AD中断服务函数 中断号22
#pragma vector = 24 // IAR中的中断号,要在STVD中的中断号上加2
__interrupt void ADC_Handle( void )
{ADC_CSR &= ~0x80; // 转换结束标志位清零 EOC//默认左对齐 读数据时先读高高8位 再读低8位DATAH = ADC_DRH; // 读出ADC结果的高8位DATAL = ADC_DRL; // 读出ADC结果的低8位ADC_flag = 1; // ADC中断标志 置1
}
下来再主程序中就可以通过PD6引脚读取AD采样值,并通过PD5引脚输出采样到的值。
#include "iostm8s103F3.h"
#include "main.h"
#include "led.h"
#include "adc.h"
#include "stdio.h"
#include "delay.h"
#include "stdlib.h"
#include "uart.h"u16 val_ch6 = 0;void SysClkInit( void )
{CLK_SWR = 0xe1; //HSI为主时钟源 16MHz CPU时钟频率CLK_CKDIVR = 0x00; //CPU时钟0分频,系统时钟0分频
}void main( void )
{u8 i=0;__asm( "sim" ); //禁止中断SysClkInit();delay_init( 16 );LED_GPIO_Init();Uart1_IO_Init();Uart1_Init( 9600 );ADC_GPIO_Init();__asm( "rim" ); //开启中断while( 1 ){LED = ~LED; for(i=0;i<10;i++)val_ch6 = ReadVol_CH6();delay_ms( 100 );printf( "%d\r\n", val_ch6);delay_ms( 200 );}
}
通过测试后发现这种方案可行,串口的发送功能和ADC采样功能可以同时使用。也就是说在使用串口的时候,不一定发送引脚和接收引脚每次必须同时使用,可以根据情况,单独使用串口的发送或者接收引脚。
STM8单片机串口发送引脚和接收引脚分开使用相关推荐
- 51单片机 串口发送数据(只是发送)
51单片机 串口发送数据(只是发送)用于调试. #include <reg51.h>#define uchar unsigned char #define uint unsigned in ...
- 51单片机串口发送汉字显示乱码问题
前一段时间做蓝牙通信,单片机串口发送汉字总显示乱码,代码如下: //发送一个字节 void SendByte(unsigned char dat) { SBUF = dat; while(!TI); ...
- 51单片机串口通信(字符串接收和发送)
转自:http://www.cnblogs.com/weifeng727/category/845655.html #include<reg52.h>//----------------- ...
- 51单片机串口通信模板_51单片机串口通信(字符串接收和发送)(示例代码)
1 #include 2 3 //------------------串口通信协议-----------------//4 /* 5 客户端数据包格式解释(长度恒为15):6 例如:A01_fmq_0 ...
- 单片机串口发送数据很慢?这种方法帮助你提高!
大家好,我是张巧龙,本文介绍如何使用带FIFO的串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法:之后介绍一种特殊的串口数据发送方法,可在避免使用串口发送中断的情况下,提高系统的响应 ...
- STM8单片机串口驱动的深度解析
串口是单片机最重要的外设之一,在很多项目开发中都有应用,Lora模块的外部通讯方式就是串口. 本节简单的和大家解析一下串口通讯及驱动代码的编程. STM8L101F3单片机支持一路串口通讯.我们先看一 ...
- STM32单片机串口空闲中断+DMA接收不定长数据
在上一篇文章STM32单片机串口空闲中断接收不定长数据中介绍了利用串口空闲中断接收不定长数据,这种方式有一个问题就是串口每接收到一个字节就会进入一次中断,如果发送的数据比较频繁,那么串口中断就会不停打 ...
- STM32单片机串口发送ASCII码
例如单片机向串口发送ASCII码$01,play只需要发送其对应的十六进制数,如下: $对应0x24 0对应0x30 1对应0x31 ,对应0x2C P对应0x70 l对应0x6C a对应0x61 y ...
- 51单片机串口发送多个16进制数据
串口发收数据 发送主要逻辑 接收主要逻辑 计算波特率 完整代码 避坑指南 发送主要逻辑 一:声明一个你要发送的字符串列表 unsigned char code table[]={0x7E,0x03,0 ...
最新文章
- python入门实践1-11课视频分享
- 【Linux】一步一步学Linux——export命令(211)
- leetcode 53. 最大子序和(C语言)
- 【手算】行列式树形展开
- 转:有关常量的知识点
- Bash shell脚本打印出正在执行的命令
- leetcode题解41-缺失的第一个正数原来如此简单
- rhel修改hostname_RHEL7 -- 修改主机名
- AbortController 中止一个或多个Web请求
- 织梦支持html5吗,自动更新HTML FOR DedeCMS V5.3(支持首页,列表页,文章页)
- 【莫队算法】【权值分块】bzoj3920 Yuuna的礼物
- ABAP:cl_system_uuid=>create_uuid_c32_static( )
- 取汉字拼音首字母的方法
- Excel数据可视化表盘模板
- vue lic在element-ui中使用阿里巴巴矢量图标库iconfont图标
- 移动支付的方式有哪些拾方易告诉你
- MacBook远程桌面Windows使用Microsoft Remote Desktop for Mac_亲测使用
- SNF快速开发平台MVC-名片管理(实际名片样式)
- 【MySQL从入门到精通】【高级篇】(二十五)EXPLAIN中ref、rows、filtered、Extra字段的剖析
- SX1278调试记录