程序包含TM1618驱动的4位或5位共阴数码管函数,包含ADC采集函数,求平均函数,
实现STM8S005单片机B0口采集后,将电压值用4位或5位共阴数码管显示。
在IAR环境编译通过
下面贴出main.c程序 :
// 要用到stm8s_clk.c和stm8s_gpio.c
// 要用到stm8s_adc1.c,该文件头要有 #include "stm8s.h"和 #include "stm8s_adc1.h"
// 且"stm8s.h"放在"stm8s_adc1.h"之前,否则编译出错
//******************************************************************************************
//
//#include "stm8s.h" //用 V2.0.0 25-February-2011 版本
#include "stm8s_gpio.h" //用 V2.0.0 25-February-2011 版本
#include "stm8s_clk.h" //用 V2.0.0 25-February-2011 版本
#include "stm8s_adc1.h" //用 V2.1.0 18-November-2011 版本
void command(unsigned char com) ; //1618命令参数com函数
void send_8bit(unsigned char dat); //1618发送显示参数dat的函数
void TM1618_IOset();
void TM1618_CMDset();
void dpy(unsigned int sz); //显示函数
void Adc_cfg(); //ADC配置函数
void adc_zs8(); //ADC采集函数
unsigned int sz=0; // TM1618 要显示的数值 全局变量
//*****************************************************************************
// 定义数据 数码管0-9 4位8段模式下,共阴数码管0-9的编码
// 高8位:***edcba 低8位:**pgf***
unsigned const CODE[ ][2]={{0x1f,0x08},{0x06,0x00},{0x1b,0x10},{0x0f,0x10},
{0x06,0x18},{0x0d,0x18},{0x1d,0x18},{0x07,0x00},
{0x1f,0x18},{0x0f,0x18} }; //可放在main 的前面
//***************************************************************
//*** 延时函数3
void delay3(void) //用于ADC开启稳定的间隔
{
unsigned int i0,i2;
for (i0=0;i0<30000;i0++)
{for (i2=0;i2<100;i2++);}
}
//***** 功能:TM1618端口设置 ***************************************************
//****************************************************************************
void TM1618_IOset(void)
{
#define DIO_0 GPIO_WriteLow(GPIOC,GPIO_PIN_6) //定义LED芯片TM1618 输入口低
#define DIO_1 GPIO_WriteHigh(GPIOC,GPIO_PIN_6) //定义LED芯片TM1618 输入口高
#define STB_0 GPIO_WriteLow(GPIOC,GPIO_PIN_7) //定义LED芯片TM1618
#define STB_1 GPIO_WriteHigh(GPIOC,GPIO_PIN_7) //定义LED芯片TM1618 低
#define CLK_0 GPIO_WriteLow(GPIOC,GPIO_PIN_5) //定义LED芯片TM1618 时钟低
#define CLK_1 GPIO_WriteHigh(GPIOC,GPIO_PIN_5) //定义LED芯片TM1618 时钟高
#define K2_0 GPIO_WriteLow(GPIOE,GPIO_PIN_5) //定义LED芯片TM1618 键扫低
#define K2_1 GPIO_WriteHigh(GPIOE,GPIO_PIN_5) //定义LED芯片TM1618 键扫高
//***********************************************
GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_HIGH_FAST ); //初始化1618的DIO
GPIO_Init(GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST ); //初始化1618的CLK
GPIO_Init(GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_HIGH_FAST ); //初始化1618的STB
GPIO_Init(GPIOE, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST ); //初始化1618的K2
}
//*** 功能:配置 TM1618 ************************************************************
//*****************************************************************************
void TM1618_CMDset(void)
{
command(0x00); //显示模式指令,0x00为 4位8段模式;0x01为 5位7段模式
command(0x40); //芯片设为写数据模式指令,地址自动加1模式;
//0x44 为写固定地址指令;0x42 为读键扫指令
command(0x88); //显示控制命令,打开显示并设置为最暗
//command(0x8F); //8F设置为最亮
//command(0x87); //87设置为关
//command(0xC0); //设置显示首地址命令,放在每次发送显示数据函数中
}
// ********** 功能:向TM1618发送1字节8位数据 *******************************************
// *************************************************************************************
void send_8bit(unsigned char dat) //dat是要发的数据变量
{
STB_0; //C7;STB=0保证“STB”为低电平,程序不依赖于之前端
//口的状态保证程序在实际运行中不会出现“端口迷失”
for(char i=0;i<8;i++) // i为轮发循环次数发送8位,移位8次一个字节
{
if (dat&0x01)
DIO_1; // C6口置高
else
DIO_0; //C6口置低
CLK_0; //C5口置低 TM1618最大输入时钟1MHz
CLK_1; //C5口置高
dat=dat>>1; //移位发送
}
}
//**** 功能:向TM1618发送命令 ***********************************************************
//***********************************************************************************
void command(unsigned char com) //com是命令字符参数变量
{
STB_1; //C7口置高
STB_0; //C7口置低
send_8bit(com); //调发送字节函数
} //下降沿后由DIO输入的第一个字节作为指令
//下降沿后由DIO输入的第一个字节作为指令
// **************************************************************
// 功能:在1-5位数码管显示数字 全局变量sz,在main中
// **************************************************************
void dpy(unsigned int sz)
{
/* //sz_n 本函数要显示数值
unsigned char i,nxs[5]; //5位显示
nxs[0]=sz_n%100000/10000;
nxs[1]=sz_n%10000/1000;
nxs[2]=sz_n%1000/100;
nxs[3]=sz_n%100/10;
nxs[4]=sz_n%10/1;
*/
unsigned char i,nxs[4]; //4位显示,定义数组nxs
if(sz>9999)
sz=9999;
nxs[0]=sz%10000/1000; //定义i为轮发次数和位数组位置 变量
nxs[1]=sz%1000/100; //sz 要显示的数值,全局变量
nxs[2]=sz%100/10; //计算显示的个十百千位
nxs[3]=sz%10/1;
command(0xC0); //轮发4位首地址设置指令,非轮发可其它地址
for(i=0;i<4;i++) //轮发次数 i=4次
//for(i=0;i<5;i++) //轮发送显示数5位
{
send_8bit(CODE[nxs[i]][0]); //i是nxs数组位置变量,如i=3,则取出nxs[3]的值
send_8bit(CODE[nxs[i]][1]); //如nxs[3]的值=7,去CODE数组取7高低8位并发送
}
STB_1; //C7=1 关片选
}
//**************************************************************************************
//*** ADC设置函数,可与ADC采集放一起,更好的是分开 *************************
void Adc_cfg(void) //使用ADC1的转换共12步
{
GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_IN_FL_NO_IT ); // 设置B0口为悬浮无中断输入
ADC1_DeInit(); // ADC1口复位初始状态
ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, // 设置ADC1为单次转
ADC1_CHANNEL_0, // 选择ADC1的通道0
ADC1_PRESSEL_FCPU_D2, // 设ADC内置时钟 2分频
ADC1_EXTTRIG_TIM, DISABLE, // 外部触发ADC事件关闭
ADC1_ALIGN_RIGHT, // 数据对齐方向右对齐
ADC1_SCHMITTTRIG_CHANNEL0, DISABLE); // 关闭ADC1通道0的施密特触发器
// ADC1_Cmd(ENABLE); // 使能ADC1
}
//************************************************************************************
//*** ADC采集函数 ********************************************************************
void adc_zs8()
{
float adsz1=0;
delay1(); //加入延时,防止采集间隔太快
ADC1_Cmd(ENABLE); // 使能ADC1
ADC1_StartConversion(); // ADC1开始转换
adsz1 = ADC1_GetConversionValue(); // 得到转换结果
//ADC1_Cmd(DISABLE); // 关闭ADC1,下次重开
adsz1=(adsz1/1024)*3339; //1024对应转速满量程 ;
sz=adsz1;
}
//*************************************************************************************
//***** 求平均函数
void sumpj(void)
{
unsigned int sum = 0;
unsigned char i;
for (i=0;i<15;i++)
{
adc_zs8(); //AD采集
sum=sum+sz; //累加
}
sz=sum/15; //求平均
}
//***********************************************************
// 主程序开始
//*********************************************************
main(void)
{
CLK_DeInit(); //复位时钟寄存器
CLK_HSICmd(ENABLE); //内部高速时钟使能
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //内部1分频 16M
sim(); //关总中断
TM1618_IOset(); //配置TM1618芯片的IO
TM1618_CMDset(); //配置TM1618芯片的指令
Adc_cfg(); //配置ADC
while (1) //死循环
{
sumpj(); //AD求平均
dpy(sz); //ADC显示
delay3();
}
}