STM8单片机串口发送引脚和接收引脚分开使用

最新更新时间:1970-01-01来源: eefocus关键字: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 );                       //输出模式 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采样功能可以同时使用。也就是说在使用串口的时候,不一定发送引脚和接收引脚每次必须同时使用,可以根据情况,单独使用串口的发送或者接收引脚。

关键字:STM8  单片机  串口 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic548632.html

上一篇:STM8学习笔记---NTC热敏电阻的使用
下一篇:STM8学习笔记---PWM变频输出

推荐阅读

车载屏的STM8单片机驱动 128x16点阵屏输出汉字
STM8单片机源程序:/*PE6  信号选择  0:控制卡   1: CPUPB7  5V电源控制  O:关   1:开*/#include <iostm8s105s4.h>#define        uint         unsigned    int#define        uchar        unsigned   
发表于 2021-11-25
STM8单片机无线315&433脉宽自适应_通用解码程序
单片机源程序如下:/*RFINT不能用PA1 要改板 改在PC6*//* Includes ------------------------------------------------------------------*/#define MAIN_C#include "ALL.h"void Delay(u16 nCount){  /* Decrement nCount value */  while (nCount != 0)  {    nCount--;  }}//10ms定时中断初始  在PWM时可更改void TIME1_CONF
发表于 2021-11-25
STM8单片机+EV1527无线315&433通用遥控解码程序
单片机源程序如下:/************************************************************************************************************        模块名称 : EV1527遥控解码*                  上升沿触发 触发中断后延时一段时间后检测引脚电平从而判断0 1采集上升沿触发后第6 10 14    &n
发表于 2021-11-25
stm8的18b20温度显示程序
单片机源程序如下:#include"stm8s.h"#include"Cry12864.h"#include"temp.h"#include"tim1.h"void LcdDisplay(int temp) ;uint a;void main( void ){ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);//内部时钟1分频16m  Ini_Lcd();//液晶初始化  Tim1_Init();//时钟初始化  while(1)  
发表于 2021-11-25
STM8单片机+EV1527无线315&433通用遥控解码
STM8_无线315&433通用解码单片机源程序如下:/************************************************************************************************************模块名称 : EV1527遥控解码*上升沿触发 触发中断后延时一段时间后检测引脚电平从而判断0 1采集上升沿触发后第6 10 14     个振荡周期时的引脚电平 RF98PT2262 连续触发是每个周期的间隔在15MS左右EV1527   宽电平时间 500US 窄 250us 同步码 5.7MS*****
发表于 2021-11-12
stm8 stm8s stm8af 485接口 modbus协议代码
本人使用stm8af62a6,stm8s和stm8af大多数是互通的,只用一个库函数62a6只能使用uart3!485接口是硬件,不需要管,任何硬件接线都可以实现代码见附件,已实现通信主函数代码,主要为初始化函数,以及modbus帧接收处理函数,帧接收处理按自己的需求自行修改,本例的处理函数为接收数据再多输出一点数据单片机源程序如下:/******************************************************************mian.c文件部分******************************************************************/void mai
发表于 2021-11-12
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved