前言:单片机价格疯长的大环境下,加上缺货,不得不考虑产品的替代芯片,这时辉芒微MCU走进我的视野。先看看这次案例的单片机信息:
总结一下:麻雀虽小五脏俱全!
再说说本次实现的案例:点亮数码管TM1635
主要是由单总线通信实现的信号通信;
详细的资料也不多说,网上一大堆;
下面展示调通的代码:
/******************************************************↓代码部分↓**************************************************************/
#include "SYSCFG.h"
#include "uart.h"
#define CLK RC1 //定义CLK RC1 PA7
#define DIO RB7 //定义DIO RB7 PA1
unsigned char CODE[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};//共阳数码管0~9字型码
unsigned char TAB[10]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};//数码管不显示
void Delay_5us_635(void)
{
NOP();NOP();
}
/*-------------------------------------------------
* 函数名称:DelayUs
* 功能: 短延时函数 --16M-2T--大概快1%左右.
* 输入参数:Time延时时间长度 延时时长Time Us
* 返回参数:无
-------------------------------------------------*/
void DelayUs(unsigned char Time)
{
unsigned char a;
for(a=0;a<Time;a++)
{
NOP();
}
}
/*-------------------------------------------------
* 函数名称:DelayMs
* 功能: 短延时函数
* 输入参数:Time延时时间长度 延时时长Time ms
* 返回参数:无
-------------------------------------------------*/
void DelayMs(unsigned short Time)
{
unsigned short a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<5;b++)
{
DelayUs(197); //快1%
}
}
}
/*-------------------------------------------------
* 函数名称:DelayS
* 功能: 短延时函数
* 输入参数:Time延时时间长度 延时时长Time S
* 返回参数:无
-------------------------------------------------*/
void DelayS(unsigned char Time)
{
unsigned char a,b;
for(a=0;a<Time;a++)
{
for(b=0;b<10;b++)
{
DelayMs(100);
}
}
}
void POWER_INITIAL (void)
{
OSCCON = 0B01110001; //WDT 32KHZ IRCF=111=16MHZ
//Bit0=1,系统时钟为内部振荡器
//Bit0=0,时钟源由FOSC<2:0>决定即编译选项时选择
INTCON = 0; //暂禁止所有中断
PORTA = 0B00000000;
TRISA = 0B11111111; //PA输入输出 0-输出 1-输入
PORTB = 0B00000000;
TRISB = 0B11111111; //PB输入输出 0-输出 1-输入
PORTC = 0B00000000;
TRISC = 0B11111111; //PC输入输出 0-输出 1-输入
WPUA = 0B00000000; //PA端口上拉控制 1-开上拉 0-关上拉
WPUB = 0B00000000; //PB端口上拉控制 1-开上拉 0-关上拉
WPUC = 0B00000000; //PC端口上拉控制 1-开上拉 0-关上拉
WPDA = 0B00000000; //PA端口上拉控制 1-开下拉 0-关下拉
WPDB = 0B00000000; //PB端口上拉控制 1-开下拉 0-关下拉
WPDC = 0B00000000; //PC端口上拉控制 1-开下拉 0-关下拉
PSRC0 = 0B11111111; //PORTA,PORTB源电流设置最大
//BIT7~BIT6:PORTB[7:4]源电流能力控制,BIT5~BIT4:PORTB[3:0]源电流能力控制
//BIT3~BIT2:PORTA[7:4]源电流能力控制,BIT1~BIT0:PORTA[3:0]源电流能力控制
PSRC1 = 0B11111111; //PORTC,PORTD源电流设置最大
//BIT7~BIT6:PORTD[7:4]源电流能力控制,BIT5~BIT4:PORTD[3:0]源电流能力控制
//BIT3~BIT2:PORTC[7:4]源电流能力控制,BIT1~BIT0:PORTC[3:0]源电流能力控制
PSINK0 = 0B11111111; //PORTA灌电流设置最大 0:最小,1:最大
PSINK1 = 0B11111111; //PORTB灌电流设置最大 0:最小,1:最大
PSINK2 = 0B11111111; //PORTC灌电流设置最大 0:最小,1:最大
ANSELA = 0B00000000; //全为数字管脚
}
void I2CInit_635() //GPIO初始化
{
TRISB7=0; //PB7 推完输出 DIO
TRISC1=0; //PB7 推完输出 CLK
}
/********************Start函数*************************/
void I2CStart_635()
{
DIO=1;
Delay_5us_635();
CLK=1;
Delay_5us_635();
DIO=0;
Delay_5us_635();
CLK=0;
}
/********************Stop函数*************************/
void I2CStop_635()
{
DIO=0;
Delay_5us_635();
CLK=1;
Delay_5us_635();
DIO=1;
}
/***************应答函数**************/
void I2CAsk_635()
{
unsigned short count1;
CLK=0; //判断芯片发过来的ACK应答信号
Delay_5us_635();
CLK=1;
TRISB7=1; //PB7 上拉输入 DIO
WPUA |= 0x80; //上拉 引脚设置输出时会自动关断
while(DIO)
{
count1++;
if(count1==200)
{
count1=0;
break;
}
}
// CLK=1;
// Delay_5us_635();
TRISB7=0; //PB7 推完输出 DIO
CLK=0;
}
/***************发送8bit数据,从低位开始**************/
void I2CWritebyte_635(unsigned char oneByte)
{
unsigned char i;
for(i=0;i<8;i++)
{
CLK=0;
Delay_5us_635();
if(oneByte&0x01) {
DIO=1;
}
else {
DIO=0;
}
oneByte=oneByte>>1;
CLK=1;
Delay_5us_635();
} //8位数据传送完
I2CAsk_635();
}
/************显示函数,固定地址写数据************/
void disp(unsigned char add, unsigned char value)
{
I2CStart_635();
I2CWritebyte_635(0x44); //数据命令设置:固定地址,写数据到显示寄存器
I2CStop_635();
I2CStart_635();
I2CWritebyte_635(add); //地址命令设置:写入add对应地址
// UART1_SendByte(CODE[value]);
I2CWritebyte_635(CODE[value]); //给add地址写数据
I2CStop_635();
I2CStart_635();
I2CWritebyte_635(0x8a); //显示控制命令:开显示,脉冲宽度为4/16.
I2CStop_635();
}
void disp0(unsigned char add, unsigned char value)
{
I2CStart_635();
I2CWritebyte_635(0x44); //数据命令设置:固定地址,写数据到显示寄存器
I2CStop_635();
I2CStart_635();
I2CWritebyte_635(add); //地址命令设置:写入add对应地址
// UART1_SendByte(TAB[value]);
I2CWritebyte_635(TAB[value]); //给add地址写数据
I2CStop_635();
I2CStart_635();
I2CWritebyte_635(0x8a); //显示控制命令:开显示,脉冲宽度为4/16.
I2CStop_635();
}
/************显示2位数字************/
void disp2(unsigned char num)
{
if(num/10==0)
disp0(0xc0,0);
else
disp(0xc0,num/10);
disp(0xc2,num%10);
}
/************关闭显示************/
void disp_off()
{
disp0(0xc0,0);
disp0(0xc2,0);
}
main()
{
POWER_INITIAL();
I2CInit_635();
disp_off();
// Uart1_init(115200);
// DelayMs(100);
while(1){
disp2(14);
DelayMs(500);
disp2(36);
DelayMs(500);
// UART1_SendByte(0xff);
}
}
/******************************************************↑代码部分↑**************************************************************/
主要说一下在调试这段代码遇到的问题:
ACK应答这块逻辑很重要,我之前在芯圣上面的代码逻辑在辉芒MCU上完全没有用,经过自己的一番调试终于点亮了数码管。
|