STC15频率产生器(粗调+微调+数码管显示)完整代码

时间:2022-11-17 07:16:20


#include "stc15.h"

#include "intrins.h"

#include "gpio.h"

#include "595hc.h"

#define MAIN_Fosc 11059200L //定义主时钟

u16 counter = 0;

u8 countdown = 5;

u16 i,j,k;

bit start_flag = 0;

bit next_flag = 0;

bit confirm_flag = 0;

bit up = 0;

bit down = 0;

u16 Fre_input = 0;

u16 Fre_counter = 0;

u8 code start[8] = {1,22,24,25,26,17,17,17};

// Y P04 P05 P06 P07

// | | | |

// X | | | |

// P00 ---- K00 ---- K01 ---- K02 ---- K03 ----

// | | | |

// P01 ---- K04 ---- K05 ---- K06 ---- K07 ----

// | | | |

// P02 ---- K08 ---- K09 ---- K10 ---- K11 ----

// | | | |

// P03 ---- K12 ---- K13 ---- K14 ---- K15 ----

// | | | |

u8 KeyCode = 0; //给用户使用的键码, 1~16有效

u8 IO_KeyState = 0, IO_KeyState1 = 0, IO_KeyHoldCnt = 0; //行列键盘变量

static u8 get_flag = 1;

void IO_KeyDelay(void)

{

i = 60;

while (--i);

}

void IO_KeyScan(void) //50ms call

{

j = IO_KeyState1; //保存上一次状态

P0 = 0xf0; //X低,读Y

IO_KeyDelay();

IO_KeyState1 = P0 & 0xf0;

P0 = 0x0f; //Y低,读X

IO_KeyDelay();

IO_KeyState1 |= (P0 & 0x0f);

IO_KeyState1 ^= 0xff; //取反

if (j == IO_KeyState1) //连续两次读相等

{

j = IO_KeyState;

IO_KeyState = IO_KeyState1;

if (IO_KeyState != 0) //有键按下

{

F0 = 0;

if (j == 0) F0 = 1; //第一次按下

else if (j == IO_KeyState)

{

if (++IO_KeyHoldCnt >= 20) //1秒后重键

{

IO_KeyHoldCnt = 18;

F0 = 1;

}

}

if (F0)

{

next_flag = 1;

switch(IO_KeyState)

{

case 0x11: get_flag = 0 ;break;//0

case 0x12: get_flag = 1 ;break;//1

case 0x14: get_flag = 2 ;break;//2

case 0x18: get_flag = 3 ;break;//3

case 0x21: get_flag = 4 ;break;//4

case 0x22: get_flag = 5 ;break;//5

case 0x24: get_flag = 6 ;break;//6

case 0x28: get_flag = 7 ;break;//7

case 0x41: get_flag = 8 ;break;//8

case 0x42: get_flag = 9 ;break;//9

case 0x44: get_flag = 10 ;break;//a

case 0x48: get_flag = 11 ;break;//b

case 0x81: get_flag = 12 ;break;//c

case 0x82: up = 1 ;break;//d

case 0x84: down = 1 ;break;//e

case 0x88: IAP_CONTR = 0x20;break;//复位

default: get_flag = 16 ;break;

}

}

}

else IO_KeyHoldCnt = 0;

}

P0 = 0xff;

}

/********************延时函数******************************/

void Delay1ms()//@11.0592MHz

{

_nop_();

_nop_();

_nop_();

i = 11;

j = 190;

do

{

while (--j);

} while (--i);

}

void Delay_ms(u16 xms)

{

for (k=0;k<xms;k++)

{

Delay1ms();

}

}

/********************** Timer0初始化 ************************/

void Timer0Init(void)//1毫秒 @11.0592MHz

{

AUXR = 0x80;//定时器时钟1T模式

TMOD = 0x00;//设置定时器模式

TL0 = 0xCD;//设置定时初值

TH0 = 0xD4;//设置定时初值

EA = 1; //开启总中断

ET0 = 1;//允许定时器0中断

TF0 = 0;//清除TF0标志

TR0 = 1;//定时器0开始计时

}

/********************** Timer0中断函数 ************************/

void timer0 (void) interrupt 1

{

counter++;

Fre_counter++;

DisplayScan();

}

/********************** 频率产生 ************************/

void Fre_output(u16 Fre)//T=Fre(ms);f=1000/Fre

{

LED8[0] = 15; //F

LED8[1] = 29; //r

LED8[2] = 14; //E

LED8[3] = 17; //-

LED8[4] = 17; //-

Fre = 500 / Fre;

if(Fre_counter >= Fre)

{

P16 = !P16;

Fre_counter = 0;

}

}

/********************** 步进加_减 ************************/

//返回1:加

//返回0:减

int up_down(bit up,bit down)

{

if(up == 1)//步进 - 加1

{

LED8[7] = LED8[7] + 1;

if(LED8[7] == 10)

{

if(LED8[6] == 9)

{

if(LED8[5] == 9)

{

LED8[7] = 9;

LED8[6] = 9;

LED8[5] = 9;

}

else

{

LED8[7] = 0;

LED8[6] = 0;

LED8[5] ++;

}

}

else

{

LED8[7] = 0;

LED8[6] ++;

}

}

return 1;

}

else if (down == 1)//步进 - 减1

{

LED8[7] = LED8[7] - 1;

if(LED8[7] < 0)

{

if(LED8[6] == 0 )

{

if(LED8[5] == 0)

{

LED8[7] = 0;

LED8[6] = 0;

LED8[5] = 0;

}

else

{

LED8[7] = 9;

LED8[6] = 9;

LED8[5] --;

}

}

else

{

LED8[7] = 9;

LED8[6] --;

}

}

return 0;

}

}

/********************** 主函数 ************************/

void main(void)

{

GPIO();

Timer0Init();

P16 = 1;

P17 = 1;

for (k = 0; k < 8; k++) LED8[k] = 17;

Fre_counter = 0;

counter = 0;

while(1)

{

if(counter >= 50) //50ms扫描键盘

{

IO_KeyScan();

counter = 0;

}

if(next_flag==0) //提示信息:input

{

for(i=0; i<5; i++) LED8[i] = start[i];

}

if(next_flag==1) //有按键按下

{

if(get_flag != 12) //输入目标频率:10~999

{

LED8[5] = LED8[6];//移位

LED8[6] = LED8[7];

LED8[7] = get_flag;

next_flag = 0;

}

else //确认按键

{

Fre_input = LED8[5] * 100 + LED8[6] * 10 + LED8[7];

switch(up_down(up,down)) //步进微调

{

case 0: Fre_input --; //减1

down = 0;

break;

case 1: Fre_input ++; //加1

up = 0;

break;

default:break;

}

Fre_output(Fre_input);

P17 = !P17;

}

}

}

}