芯圣のHC89S003多路ADC采样代码
芯圣のHC89S003多路ADC采样代码分享及下载器(hc-link)使用因为项目需求以及朋友介绍,偶然接触到了芯圣的这一款国产的hc89s003,主要是需要用到多路ADC转换,stm8s003f4p6只有5x10位ADC,但是hc89s003有(11+2)x12位ADC 、(11路外部+2路内部),一片更比两片强。而且stm8一片是1块多,hc89s003是不到一块(邮费20是真的贵 )。
图一、STM8S103F4P6引脚图
本帖最后由 远芳侵古道 于 2022-2-26 23:29 编辑
图二、HC89S003F4引脚图
先是买了芯片以及最小系统,但拿到快递琢磨了2小时我哭了,这玩意必须专门的下载器,不能用ch340、st-link、j-link一类的,买的芯片就这样被我闲置了两个月。 听说芯圣淘宝在搞活动,一元送开发版就去白**了一块,就是下图这个玩意,搞到一个免费的下载器、怎么也要给点儿面子用一下他的芯片吧(其实是舍不得之前买的芯片还有最小系统 )
图三、一元下载器白**板 按照官方的资料包,又是驱动又目录下的,整了半天连官方给的例程都下载不进去,提示没有连接到下载器,板子根本没有连上下载器,最后发现是数字签证的问题。
我是使用的是WIN7系统,可能win10,winxp有所差异 步骤如下:
1. 打开我的电脑,选中控制面板
2. 找到设备管理器,双击打开
3. 找到COM端口,你会发现驱动并没有安装成功 系统提示,驱动程序的数字签证无法验证。
解决办法有两种,一是关系统的数字签字,二是禁用数字签证。可以根据不同的系统进行百度,一下是win7系统的处理方法。https://jingyan.baidu.com/article/acf728fd495b9ff8e410a377.html
完成修改以后,再接上驱动就会发现神奇的事情发生了… 红叉叉没了,说明HC-LINK安装上了,这样一来就可以下载代码了。 以下是多路AD的程序代码供参考
芯片:hc89s003
下载器:一元白**板
功能:10路AD转换
端口设置—gpio.h
#define P000
#define P011
#define P02 2
#define P03 3
#define P04 4
#define P05 5
#define P06 6
#define P07 7
#define P20 20
#define P21 21
#define P22 22
#define P23 23
#define P24 24
#define P25 25
#define P26 26
#define P27 27
#define P10 10
#define P11 11
#define IO_IN_FL_NO_SMT 0x00 //!<0000输入(无SMT)
#define IO_IN_PD_NO_SMT 0x01 //!<0001带下拉输入(无SMT) P2.3/P2.4/P2.5/P2.7不支持此功能
#define IO_IN_PU_NO_SMT 0x02 //!<0010带上拉输入(无SMT) P2.3/P2.4/P2.5/P2.7不支持此功能
#define IO_IN_AN0x03 //!<0011带模拟输入
#define IO_IN_SMT0x04 //!<0100输入(SMT)
#define IO_IN_PD_SMT0x05 //!<0101带下拉输入(SMT)
#define IO_IN_PU_SMT0x06 //!<0110带上拉输入(SMT)
#define IO_IN_AN_PU_PD 0x07 //!<0111带上下拉模拟输入仅P2.3/P2.4/P2.5/P2.7支持此功能
#define IO_OUT_PP0x08 //!<1x00推挽输出
#define IO_OUT_OD0x09 //!<1x01开漏输出
#define IO_OUT_PU0x0A //!<1x10带上拉开漏输出
void GPIO(u8 m,u8 n)//HC89S003F4管脚快速设置函数by abin 。 m为管脚 P0.1=01P1.0=10 等,n为管脚状态,见上面或数据手册说明
{
switch (m)
{
case 00:P0M0 = P0M0&0xF0|n;break;
case 01:P0M0 = P0M0&0x0F|(n*16);break;
case 02:P0M1 = P0M1&0xF0|n;break;
case 03:P0M1 = P0M1&0x0F|(n*16);break;
case 04:P0M2 = P0M2&0xF0|n;break;
case 05:P0M2 = P0M2&0x0F|(n*16);break;
case 06:P0M3 = P0M3&0xF0|n;break;
case 07:P0M3 = P0M3&0x0F|(n*16);break;
case 20:P2M0 = P2M0&0xF0|n;break;
case 21:P2M0 = P2M0&0x0F|(n*16);break;
case 22:P2M1 = P2M1&0xF0|n;break;
case 23:P2M1 = P2M1&0x0F|(n*16);break;
case 24:P2M2 = P2M2&0xF0|n;break;
case 25:P2M2 = P2M2&0x0F|(n*16);break;
case 26:P2M3 = P2M3&0xF0|n;break;
case 27:P2M3 = P2M3&0x0F|(n*16);break;
case 10:P1M0 = P1M0&0xF0|n;break;
case 11:P1M0 = P1M0&0x0F|(n*16);break;
default:break;
}
}
串口重定义-----uart.h
/**********************************发送一个ASCII码*************************************/
void Printascii(char buf)
{
SBUF = buf;
while(!(SCON & 0x02));
SCON &= ~ 0x02;
}
/**********************************发送一个字符串´®**************************************/
void PrintString(char* buf)
{
int i;
int sub = 0;
while(buf != 0)
{
SBUF = buf; //将需要发送的字符载入寄存器
while(!(SCON & 0x02)); //判断发送完成?
SCON &=~ 0x02; //清标志位
sub++;
i=20; while(i>1) i--;
}
}
char putchar(char c)//重定义putchar
{
char i=10;
Printascii(c);
while(i>1)i--;
return c;
}
void Delay_ms(unsigned int fui_i)//毫秒延时
{
unsigned int fui_j;
for(;fui_i > 1;fui_i --)
for(fui_j = 1596;fui_j > 1;fui_j --);
}
void Delay_2us(unsigned int fui_i)//微秒延时
{
while(fui_i--);
}
主程序----main.c
#define ALLOCATE_EXTERN
#include "HC89S003F4.h"
#include "stdio.h"
#include "gpio.h"
#include "uart.h"
#define AD_num 10 //通道数
unsigned intgui_AdcValue_a = {0x00};
//存放转换后的数值
unsigned char guc_AdcChannel_a[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
//ADC通道预设置
unsigned char guc_Count = 0; //通道计数
char sendbuf[] = " I'm the Id ";
char getbuf;
unsigned int flag=0,num=5,i=0,mode=0;
/***************************************************
主程序
****************************************************/
void main()
{
WDTCCR = 0x00;
CLKSWR = 0x51;
CLKDIV = 0x01;
/**********************************UART端口设置¯**************************************/
// P2M0 = P2M0&0x0F|0x80; //P21TX
GPIO(P10,IO_OUT_OD); //P10TX
// P0M1 = P0M1&0x0F|0x20; //P03RX
GPIO(P11,IO_IN_FL_NO_SMT); //P11TX
// TXD_MAP = 0x21; //TX端口映射到P21
TXD_MAP = 0x10; //TX端口映射到P10
// RXD_MAP = 0x03; //RX端口映射到P03
RXD_MAP = 0x11; //RX端口映射到P11
T4CON = 0x06; //模式6
//波特率 38400---FFE6
//波特率 9600---FF98
TH4 = 0xFF;
TL4 = 0xE6;
SCON2 = 0x02;
SCON = 0x10;
IE |= 0X10;
EA = 1;
/************************************ADC设置*****************************************/
GPIO(P00,IO_IN_AN);
GPIO(P01,IO_IN_AN);
GPIO(P02,IO_IN_AN);
GPIO(P03,IO_IN_AN);
GPIO(P04,IO_IN_AN);
GPIO(P05,IO_IN_AN);
GPIO(P06,IO_IN_AN);
GPIO(P07,IO_IN_AN);
GPIO(P20,IO_IN_AN);
GPIO(P21,IO_IN_AN);
ADCC0 = 0x80;
Delay_2us(10);
ADCC1 = 0x00;
ADCC2 = 0x4D;
IE1 |= 0x20;
EA = 1;
ADCC0 &=~ 0x20;
Delay_2us(10);
ADCC0 |= 0x40;
while(1)
{
printf("AD_a");
for(i=0;i<AD_num;i++)
{
printf("%d",gui_AdcValue_a);
}
printf("\r\n");
Delay_ms(500);
}
}
}
void adc_do(unsigned int ad_value)
{
gui_AdcValue_a = ad_value;
guc_Count++;
if(guc_Count >=AD_num)guc_Count=0;
ADCC1 = (ADCC1&(~0x0f))|(guc_AdcChannel_a);
Delay_2us(10);
}
/*******************************ADC中断**************************************/
void ADC_Rpt() interrupt ADC_VECTOR
{
ADCC0 &=~ 0x20;
adc_do(ADCR);
ADCC0 |= 0x40;
}
/**********************************串口中断**************************************/
void UART1_Rpt(void) interrupt UART1_VECTOR
{
char temp;
if(SCON & 0x01)
{
temp= SBUF;
// if(flag==0) uart_do(temp);
SCON &=~ 0x01;
}
}
以上为部分修改以后的代码,其中AD转换部分没有修改,可以直接使用,主要添加AD_set()函数 ,用于对通道的选择,之所以没有使用全部引脚打开而选择通道切换,是因为同时打开10个通道会出现前8个引脚失效,使用单通道切换就可以完成10路的ADC 转换,有兴趣的可以修改一下试一试第11路(P22)的ADC啊,但是同时开启不能实现转换的具体原因本人才学薄浅,还望巨佬指点 。
询问客服以后是官方历程的问题,修改以后就能同时使用了!!!
其中使用gpio.h快捷端口配置来自博客https://blog.csdn.net/silno/article/details/80412869,差点儿忘记了。
需要在做项目的过程中经历磨难
为什么同时打开10个通道会出现前8个引脚失效?