【STC8】ADC值串口输出

  • 基于STC8A8K64D4核心板
  • keli5编写,11.0592频率下烧录

前言

  STC8A8K64D4,它具有高速12位A/D转换器。其中16个管脚与ADC测量密切相关,其中15个为ADC外部测量通道,而1个则是用来获取出厂时校准的1.19V电压参考源的内部测量通道。据官方手册介绍,该芯片ADC的最快速度为每秒800K,每秒可进行80万次ADC转换。此外,内部电压参考源可用于反推测量未知外部电压。如需更详细信息,可查阅芯片手册以获取应用方法。本文章,只是介绍ADC获取和串口输出的基本应用。

现象

  本文工程文件实现现象:直接输出ADC值,利用STC8A8K64D4核心板的P10做测试,有数值的时候是引脚浮空的时候,为0时是我用一根杜邦线将P10和GND连接,就数值就立马出来了。

在这里插入图片描述

过程

  工程文件基本分成以下三大模块,库中都是些基本案例和注释,方便理解应用。

  • ADC.h ADC应用调用库
  • CK.h 串口调用库
  • GPIO GPIO引脚模式切换库
  1. mian.c

    #include <STC8A8K64D4.H>
    #include <CK.H>
    #include "intrins.h"
    #include <ADC.H>
    #include <GPIO.H>
    
    void main()
    {
    	CK_Init();
    	while(1)
    	{
            //调用P10口读取ADC值
    		ADC_Use(0);
    	}
    }
    
  2. ADC.h

    /*
    	ADC库
    	基于STC8,11.0592频率下
    	功能:调用ADC
    */
    
    /*ADC通道
    	0~7(P10~P17)	8~14(P00~P06)	15(测试内部1.19V)
    */
    
    //ADC
    //参数channel:	范围:0~15(周期模式)	作用:ADC通道
    void ADC_Use(unsigned char channel)
    {
    	P_SW2|=0x80;
    	ADCTIM=0x3f;
    	P_SW2&=0x7f;
        ADCCFG = 0x0f;                           //设置ADC时钟为系统时钟/2/16/16
    	ADC_CONTR = 0x80;
        ADC_CONTR = 0x80|channel;                //使能ADC模块
    
    	ADC_CONTR |= 0x40;                      //启动AD转换
    	_nop_();
    	_nop_();
    	while (!(ADC_CONTR & 0x20));            //查询ADC完成标志
    	ADC_CONTR &= ~0x20;                     //清完成标志
    	//P2 = ADC_RES;                         //读取ADC结果
    	CK_SendIntX(ADC_RES);
    
    }
    
  3. GPIO.h

    /*
    	GPIO库
    	基于STC8下
    	功能:单个,整组IO口引脚切换
    
    */
    
    /*官方文档介绍
    	I/O口工作模式
    	准双向口:(传统8051端口模式,弱上拉)灌电流可达20mA,拉电流为270~150uA(存在制造误差)
    	推挽输出:(强上拉输出,可达20mA,要加限流电阻)
    	高阻输入:(电不能流入也不能流出)
    	开漏输出:(Open-Drain) ,内部上拉电阻断开正在联网识别并翻译.开漏模式既可读外部状态也可对外输出(高电平或低电平)。
    			如要正确读外部状态或需要对外输出高电平,需外加上拉电阻,否则读不到外部状态,也对外输不出高电平。
    */
    
    //单个IO口模式切换
    //参数io:		范围:1~XX(具体看有多少pin脚)	作用:单个IO口号
    //参数mod:		范围:0~3					作用:模式	0:准双向口	1:推挽输出	2:高阻输入	3:开漏输出
    //例如:P20要切换成推挽输出就是	GPIO_Mod(20,1);		P30要切换成开漏输出就是	GPIO_Mod(30,3);
    void GPIO_Mod(unsigned char io,mod)
    {
    	char ioa=io%10;
    	char moda=mod%2;
    	char modb=mod/2;
    	switch(io/10)
    	{
    		case 0:
    			P0M0=P0M0&((0x00|moda)<<ioa);
    			P0M1=P0M1&((0x00|modb)<<ioa);
    		break;
    		case 1:
    			P1M0=P1M0&((0x00|moda)<<ioa);
    			P1M1=P1M1&((0x00|modb)<<ioa);
    		break;
    		case 2:
    			P2M0=P2M0&((0x00|moda)<<ioa);
    			P2M1=P2M1&((0x00|modb)<<ioa);
    		break;
    		case 3:
    			P3M0=P3M0&((0x00|moda)<<ioa);
    			P3M1=P3M1&((0x00|modb)<<ioa);
    		break;
    		case 4:
    			P4M0=P4M0&((0x00|moda)<<ioa);
    			P4M1=P4M1&((0x00|modb)<<ioa);
    		break;
    		case 5:
    			P5M0=P5M0&((0x00|moda)<<ioa);
    			P5M1=P5M1&((0x00|modb)<<ioa);
    		break;
    		case 6:
    			P6M0=P6M0&((0x00|moda)<<ioa);
    			P6M1=P6M1&((0x00|modb)<<ioa);
    		break;
    		case 7:
    			P7M0=P7M0&((0x00|moda)<<ioa);
    			P7M1=P7M1&((0x00|modb)<<ioa);
    		break;
    	}
    }
    
    //整组IO模式切换
    //参数io:		范围:0~7(组)		作用:IO口组
    //参数mod:		范围:0~3			作用:模式	0:准双向口	1:推挽输出	2:高阻输入	3:开漏输出
    //例如:P1组要切换成推挽输出就是	GPIO_Mod(1,1);		P3组要切换成开漏输出就是	GPIO_Mod(3,3);
    void GPIO_Mods(unsigned char io,mod)
    {
    	char ioa=io%10;
    	char moda=0x00;
    	char modb=0x00;
    	if(mod%2) moda=0xff;
    	if(mod/2) modb=0xff;
    	switch(io)
    	{
    		case 0:
    			P0M0=moda;
    			P0M1=modb;
    		break;
    		case 1:
    			P1M0=moda;
    			P1M1=modb;
    		break;
    		case 2:
    			P2M0=moda;
    			P2M1=modb;
    		break;
    		case 3:
    			P3M0=moda;
    			P3M1=modb;
    		break;
    		case 4:
    			P4M0=moda;
    			P4M1=modb;
    		break;
    		case 5:
    			P5M0=moda;
    			P5M1=modb;
    		break;
    		case 6:
    			P6M0=moda;
    			P6M1=modb;
    		break;
    		case 7:
    			P7M0=moda;
    			P7M1=modb;
    		break;
    	}
    }
    
  4. CK.h

    /*
    	简单串口通信库
    	.H文件通常用于配置
    	.C文件通常用于编写函数
    
    	说明:该库只是简单的应用串口1通信,和定时器1作为波特率发生器。方便调整程序。
    	功能:串口打印
    	使用说明:1.配置串口波特率,配置单片机运行频率
    			 2.调用初始化函数
    			 3.调用功能函数
    	
    	层级:一级(为最底层无需在嵌套其他库)
    	标记:XY
    */
    //基础
    void CK_Init();					//串口1初始化
    void CK_SendByte(char Data);	//发送字节
    //功能
    void CK_SendInt(int num);		//发送整型
    void CK_SendIntX(int num);		//发送整型(自动换行)
    void CK_SendFloat(float num);	//发送浮点型
    void CK_SendFloatX(float num);	//发送浮点型(自动换行)
    void CK_SendStr(char *p);		//发送字符串
    void CK_SendStrX(char *p);		//发送字符串(自动换行)
    void CK_Read();					//电脑发送数据给单片机又发回给电脑,
    

    CK.c

    #include <STC8.H>
    #include <CK.H>
    #include <stdio.H>
    #include "intrins.h"
    //配置工作环境
    #define CK_Bti 	115200    	//配置串口波特率
    #define	CK_FOSC  11059200	//单片机运行频率(默认:11.0592  (频率x10^6))
    #define CK_IntStrLen 20		//整型上限个数
    #define CK_FloatStrLen 20	//浮点型型上限个数(默认保留三位小数)
    
    #define CK_BRT  (65536 - CK_FOSC/ CK_Bti /4)
    
    bit CK_busy;			//繁忙标志
    char CK_rjs;			//接收缓冲计数
    char CK_ryjs;			//接收阅读计数
    char CK_buffer[16];		//接收缓冲
    
    //串口初始化
    void CK_Init()
    {
    	SCON=0x50;		//串口1控制寄存器			//串口1工作模式_模式1:可变波特率8位数据方式 and 允许串口接收数据
    	TMOD=0x00;		//定时器模式寄存器		//定时器/计数器1工作模式:16位自动重载模式
    	TL1=CK_BRT;		//定时器1计数寄存器(低位)
    	TH1=CK_BRT>>8;	//定时器1计数寄存器(高位)
    	TR1=1;			//定时器T1的运行控制位	//开始计数
    	AUXR=0x40;		//辅助寄存器1			//定时器1速度控制位_CPU时钟不分频分频(FOSC/1)
    	
    	ES=1;			//串口1中断开关			//打开
    	EA=1;			//中断总开关				//打开
    	
    	CK_rjs=0x00;  		
    	CK_ryjs=0x00;
    	CK_busy=0;
    }
    
    //发送字符串
    void CK_SendStr(char *p)
    {
    	while(*p)
    	{	
    		CK_SendByte(*p++);
    	}	
    }
    
    //发送字符串(自动换行)
    void CK_SendStrX(char *p)
    {
    	while(*p)
    	{	
    		CK_SendByte(*p++);
    	}
    	CK_SendStr("\r\n");
    }
    
    //发送整型
    void CK_SendInt(int num)
    {
    	char str[CK_IntStrLen];
    	sprintf(str,"%d",num);
    	CK_SendStrX(str);	
    }
    
    //发送整型(自动换行)
    void CK_SendIntX(int num)
    {
    	char str[CK_IntStrLen];
    	sprintf(str,"%d",num);
    	CK_SendStrX(str);
    }
    
    //发送浮点型
    void CK_SendFloat(float num)
    {
    	char str[CK_FloatStrLen];
    	sprintf(str,"%.3f",num);
    	CK_SendStrX(str);	
    }
    
    //发送浮点型(自动换行)
    void CK_SendFloatX(float num)
    {
    	char str[CK_FloatStrLen];
    	sprintf(str,"%.3f",num);
    	CK_SendStrX(str);
    }
    
    //发送字节
    void CK_SendByte(char Data)
    {
    	while (CK_busy);
    	CK_busy = 1;
    	SBUF = Data;
    }
    
    //串口1中断事件  分配寄存器组1
    void UartIsr() interrupt 4 using 1   
    {
    	if (TI)
    	{
    		TI = 0;
    		CK_busy = 0;
    	}
    	if (RI)
    	{
    		RI = 0;
    		CK_buffer[CK_rjs++] = SBUF;
    		CK_rjs&=0x0f;	//满16归0
    	}
    }
    
    //电脑发送数据给单片机又发回给电脑
    void CK_Read()
    {
    	if (CK_ryjs!=CK_rjs)
    	{
    		CK_SendByte(CK_buffer[CK_ryjs++]);
    		CK_ryjs &= 0x0f;
    	}
    }
    
    

总结

文章中的工程链接的分享:

链接:https://pan.baidu.com/s/1wrgfn7XZ4ci7c5qKE39hUw 提取码:w3s4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值