历史上的今天
今天是:2024年09月22日(星期日)
2021年09月22日 | STM8单片机串口发送引脚和接收引脚分开使用
2021-09-22 来源:eefocus
在使用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 ); //输出模式 TXD
PD_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 bit
UART1_CR3 = 0; //1 stop
UART1_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模块的上电完成 至少7us
ADC_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( "%drn", val_ch6);
delay_ms( 200 );
}
}
通过测试后发现这种方案可行,串口的发送功能和ADC采样功能可以同时使用。也就是说在使用串口的时候,不一定发送引脚和接收引脚每次必须同时使用,可以根据情况,单独使用串口的发送或者接收引脚。
史海拾趣
|
深圳驰泰代理中颖全系列单片机,附件为选型表,欢迎大家下载。 CHIPTECH SEMICONDUCTOR CO.,LTD 深圳市驰泰电子有限公司 hidy/王芳 QQ:313030919 MSN:wfhidy@hotmail.com Tel:86-755-33340867 Fax:86-755-33340839 Mob:13590192992 E-ma ...… 查看全部问答> |
|
我现在有480*800的一个窗口 上面有背景图和其他一些图。。都贴在上面。 当我点击任意一点。如何才能把点击后规定的区域下的图片拿出来可以用?… 查看全部问答> |
|
请高手帮帮忙: 最近想把「micro C/os-ii The Real-Time Kernel 」书中的 chapter 1 之example 1-4 移植 至 s3c2440 开发板子中,却觉得不容易上手,请高手不吝多多指教,谢谢! … 查看全部问答> |
|
这两个不都是最终都是生成arm的识别的文件,有什么区别吗,生成的格式不一样?这两个环境各生成什么格式文件,如何下载或者说用什么软件下载?有人说ads一般用于裸机编程,是这回事吗? 我是菜鸟,不要喷我,感谢啦… 查看全部问答> |
|
LM317常用作电压稳压器中的调整元件,这里给大家介绍一个不寻常的应用,只要配上不多的外部元件,可以使一个12V的小灯泡闪烁发光。 如图,采用所给的元件参数值和信号,当电路接通以后,小灯泡将以4Hz的频率闪烁,当然,若改变元件参数(R2或C ...… 查看全部问答> |
|
TI给的关于FLASH历程 void main(void) { unsigned long * Flash_ptrD; // Initialize Flash pointer Seg D unsigned long value; WDTC ...… 查看全部问答> |
|
每个上司都有自己的个性,但是你知道吗,从某种程度上讲,人们的性格是可以被稍微调整的。就拿处于热恋中的人来说,就算平时最懦弱的男人,也一定会在心爱的女人面前表现出英雄气概。 就算不是恋爱,碰到了一个楚楚可怜的女孩子,很多男 ...… 查看全部问答> |




