2024-09-01
售卖作品
00

在这里插入图片描述

main.c

c
#include <reg52.h> #include <intrins.h> #include "lcd1602.h" /* 1602显示驱动文件 调用init和显示字符串2个函数 */ #include "ds18b20.h" #include <stdio.h> #include <stdlib.h> #include <string.h> typedef unsigned int u16; typedef unsigned char u8; typedef unsigned int uint; typedef unsigned char uchar; //以下是C调低音的音频宏定义 #define L1 262 //将"L1"宏定义为低音"1"的频率262Hz 时间是1/262=3826/2 us 取半周期 #define L2 286 //将"L2"宏定义为低音"2"的频率286Hz #define L3 311 //将"L3"宏定义为低音"3"的频率311Hz #define L4 349 //将"L4"宏定义为低音"4"的频率349Hz #define L5 392 //将"L5"宏定义为低音"5"的频率392Hz #define L6 440 //将"l_a"宏定义为低音"6"的频率440Hz #define L7 494 //将"L7"宏定义为低音"7"的频率494Hz //以下是C调中音的音频宏定义 #define Z1 523 //将"Z1"宏定义为中音"1"的频率523Hz #define Z2 587 //将"Z2"宏定义为中音"2"的频率587Hz #define Z3 659 //将"Z3"宏定义为中音"3"的频率659Hz #define Z4 698 //将"Z4"宏定义为中音"4"的频率698Hz #define Z5 784 //将"Z5"宏定义为中音"5"的频率784Hz #define Z6 880 //将"Z6"宏定义为中音"6"的频率880Hz #define Z7 987 //将"Z7"宏定义为中音"7"的频率523H //以下是C调高音的音频宏定义 #define H1 1046 //将"H1"宏定义为高音"1"的频率1046Hz #define H2 1174 //将"H2"宏定义为高音"2"的频率1174Hz #define H3 1318 //将"H3"宏定义为高音"3"的频率1318Hz #define H4 1396 //将"H4"宏定义为高音"4"的频率1396Hz #define H5 1567 //将"H5"宏定义为高音"5"的频率1567Hz #define H6 1760 //将"H6"宏定义为高音"6"的频率1760Hz #define H7 1975 //将"H7"宏定义为高音"7"的频率1975Hz /* ****************************************** */ // ******** 硬件端口定义 /* ****************************************** */ sbit sound = P2 ^ 3; //蜂鸣器 /* ****************************************** */ // ******** 程序变量定义 /* ****************************************** */ unsigned int C; //储存定时器的定时常数 unsigned char u, t; //音乐所用的变量 unsigned char velocity = 50; //控制节拍使用的 这里100表示一个拍子100ms /* ****************************************** */ // ******** 音乐0 天空之城 /* ****************************************** */ //以下是《天空之城》简谱 //每行对应一小节音符 unsigned int code music0[]= { Z6,Z7,/**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1,/**/Z5,Z3,Z3, /**/Z4,Z3,Z4,H1, Z3,H1,H1,H1,/**/Z7,Z4,Z4,Z7,/**/Z7,Z6,Z7, /**/H1,Z7,H1,H3,/**/Z7,Z3,Z3, /**/Z6,Z5,Z6,H1, Z5, Z3,/**/Z4,H1,Z7,H1,/**/H2,H2,H2,H1,/**/H1,Z6,Z7,Z5,/**/Z6,H1,H2, /**/H3,H2,H3,H5, H2,Z5,Z5, /**/H1,Z7,H1,H3,/**/H3, /**/Z6,H1,Z7,H2,/**/H1,Z5,Z5, /**/H4,H3,H2,H1, H3, /**/Z3,H3, /**/H6,H5,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,H5,/**/H3,H3, H6,H5, /**/H3,H2,H1,H1,/**/H2,H1,H2,Z7,/**/Z6,Z6,Z7, /**/Z6,0xff}; //以0xff作为音符的结束标志 //以下是简谱中每个音符的节拍 //"4"对应4个延时单位,"2"对应2个延时单位,"1"对应1个延时单位 unsigned char code music0_JP[ ]= { 4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,4,12, 20,4,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, /**/20,4,4, /**/12,4,8,8, 32, 4, /**/8,4,6,8, /**/4,4,4,16, /**/8,4,6,8, /**/24,4,4, /**/12,4,8,8, 24,4,4, /**/4,4,8,8, /**/32, /**/4,8,8,6, /**/12,4,16, /**/8,8,8,8, 30, /**/20,8, /**/16,8,8, /**/4,4,16,8, /**/8,4,4,8, /**/20,8, 16,16, /**/4,20,8, /**/8,4,4,8, /**/20,4,4, /**/32}; /* ****************************************** */ /* ******** 延时100ms 控制音乐节拍 */ /* ****************************************** */ void delay1() { uint i, j; for ( i = 0; i < velocity; i++ ) for ( j = 0; j < 125; j++ ) ; } /********************************************************************************* * 【函 数 名】: void SerInit(void) * 【功 能】: 串口初始化程序 设置波特率为9600 **********************************************************************************/ //void SerInit( void ) //{ // TMOD = 0x20; /* 用定时器设置串口波特率 9600 */ // TH1 = 0xfd; /* 使用定时器1作为波特率发生器 9600波特率 */ // TL1 = 0xfd; // TR1 = 1; // REN = 1; /* 串口初始化 */ // SM0 = 0; // SM1 = 1; // EA = 1; /* 开启总中断 */ // ES = 1; /* 串口中断 */ //} #define FSOC 11059200L //晶振 #define BAUD 9600 //波特率 /* ********************************************************************************************************* * 函 数 名: bsp_InitUart * 功能说明: 初始化CPU的U串口硬件设备。未启用中断。 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void SerInit(void) { SCON = 0x50; /* 010 1 0000B,工作方式1, 8位UART,波特率可变,允许接收 */ TMOD = 0x20; /* T1工作于方式2 */ TCON = 0x40; /* 定时器1开始计数 */ TH1 = -(FSOC/BAUD/12/16); /* T1计数初值 */ TL1 = -(FSOC/BAUD/12/16); PCON = 0x80; /* SMOD置1,双倍速率 */ RI = 0; TI = 0; ES = 1;//中断 EA = 1;//总中断 } /********************************************************************************* * 【函 数 名】: void send_cmd(unsigned char dat) * 【功 能】: 串口发送数据命令 **********************************************************************************/ void send(unsigned char dat) { SBUF = dat; //发送指令到SBUF while (!TI) ; //等待发送结束 TI = 0; //清除结束标志,以便再发送数据 } /********************************************************************************* * 【函 数 名】: Print_Str(unsigned char *s) * 【功 能】: 串口发送 一个字符串 **********************************************************************************/ void Print_Str(unsigned char *s) { while (*s != '\0') { send(*s++); } } /* 显示温度 */ void DisplayTEMP( int value ) { unsigned char disp[15]; unsigned char count=0; if ( value >= 0 ) { disp[count++] = ' '; } else { disp[count++] = '-'; } disp[count++] = '0' + value % 1000 / 100; disp[count++] = '0' + value % 100 / 10; disp[count++] = '.'; disp[count++] = '0' + value % 10; disp[count++] = 0xdf; disp[count++] = 'C'; disp[count++] = 0; LCD_write_str( 5, 0, disp ); } /* pwm初始化定时器0 */ void init_timer0_pwm( void ) { TMOD &= 0xf0; TMOD |= 0x01; /* 定时器1为工作方式1 16bit */ TH0 = (65536 - 1000) / 256; TL0 = (65536 - 1000) % 256; ET0 = 1; /* 开定时器1中断 */ TR0 = 1; /* 关闭定时器 */ EA = 1; /* 开总开关 */ } /* 音乐初始化定时器0 */ void init_timer0_yinyue( void ) { TMOD &= 0xf0; TR0 = 1; ET0 = 1; /* 定时器T1中断允许 */ EA = 1; /* 开总中断 */ } int temp;//温度 u8 pwm_count = 0; u8 ZHANKONGBI = 5; /* 值越大 小灯越亮 */ char Txd_data = 0; //串口接收的数据 char mode = 0; //模式0PWM 模式1音乐 模式2温度 其他模式值无所谓 /* ****************************************** */ /* ******** 主函数 程序逻辑 */ /* ****************************************** */ sbit DULA = P2 ^ 6; sbit WELA = P2 ^ 7; sbit D6RL = P0 ^ 6; void main() { LCD_init();//初始化 LCD_write_str( 0, 1, "hello~" ); SerInit(); Print_Str("test");//测试用 DULA=1; P0=0X00; DULA=0; WELA=1; P0=0X00; WELA=0; while ( 1 ) { if ( mode == 1 ) { u = 0; /* 从第1个音符f[0]开始播放 */ while ( music0[u] != 0xff ) /* 只要没有读到结束标志就继续播放 */ { C = 460830 / music0[u]; TH0 = (8192 - C) / 32; /* 可证明这是13位计数器TH0高8位的赋初值方法 5 */ TL0 = (8192 - C) % 32; /* 可证明这是13位计数器TL0低5位的赋初值方法 */ TR0 = 1; /* 启动定时器T0 */ for ( t = 0; t < music0_JP[u]; t++ ) /* 控制节拍数 */ delay1(); /* 延时1个节拍单位 */ TR0 = 0; /* 关闭定时器T1 */ u++; /* 播放下一个音符 */ } TR0 = 0; /* 关闭定时器 */ sound = 1; /* 关闭蜂鸣器 */ }else if ( mode == 2 ) { temp = getTmpValue(); DisplayTEMP( temp ); sound = 1; delayMs(10); } } } void Uart_isr() interrupt 4 /* 中断接收程序 */ { if ( RI ) /* 判断是否接收完,接收完成后,由硬件置RI位 */ { Txd_data = SBUF; /* 读入缓冲区 */ RI = 0; /* 清标志 */ SBUF = Txd_data; while ( !TI ) ; /* 等待发送结束 */ TI = 0; /* 清除结束标志,以便再发送数据 */ if ( Txd_data == '1' ) { WELA=1; P0=0X00; WELA=0; mode = 0; init_timer0_pwm(); }else if ( Txd_data == '2' ) { if ( ZHANKONGBI < 9 ) ZHANKONGBI++; SBUF = '0' + ZHANKONGBI; while ( !TI ) ; /* 等待发送结束 */ TI = 0; /* 清除结束标志,以便再发送数据 */ }else if ( Txd_data == '3' ) { if ( ZHANKONGBI > 0 ) ZHANKONGBI--; SBUF = '0' + ZHANKONGBI; while ( !TI ) ; /* 等待发送结束 */ TI = 0; /* 清除结束标志,以便再发送数据 */ }else if ( Txd_data == '4' ) { init_timer0_yinyue(); mode = 1; WELA=1; P0=0X00; WELA=0; }else if ( Txd_data == '5' ) { mode = 5; WELA = 1; /* 改变电压之前先拉高 */ D6RL = 1; WELA = 0; /* 改变完了就拉低锁存 */ }else if ( Txd_data == '6' ) { mode = 5; WELA = 1; /* 改变电压之前先拉高 */ D6RL = 0; WELA = 0; /* 改变完了就拉低锁存 */ }else if ( Txd_data == '7' ) { mode = 2; WELA=1; P0=0X00; WELA=0; } } } sbit LED = P1 ^ 0; /* ==================定时器1中断服务程序=============== */ void timer0_server( void ) interrupt 1 { /* mode=0 pwm */ if ( mode == 0 ) { TH0 = (65536 - 1000) / 256; TL0 = (65536 - 1000) % 256; pwm_count++; if ( pwm_count == 10 ) { pwm_count = 0; LED = 0; } if ( ZHANKONGBI == pwm_count ) { LED = 1; } }else if ( mode == 1 ) { /* mode=1 yinyue */ sound = !sound; /* 将P3.7引脚输出电平取反,形成方波 */ TH0 = (8192 - C) / 32; /* 可证明这是13位计数器TH0高8位的赋初值方法 */ TL0 = (8192 - C) % 32; /* 可证明这是13位计数器TL0低5位的赋初值方法 */ } }

ds18b20.h

c
#include <reg52.h> #include <intrins.h> #include <math.h> sbit ds = P2^2; /******************************************/ //延时n ms /******************************************/ void delayMs(unsigned int a) { unsigned int i, j; for(i = a; i > 0; i--) for(j = 100; j > 0; j--); } /******************************************/ //初始化 /******************************************/ void dsInit() { unsigned int i; ds = 0; i = 100; while(i>0) i--; ds = 1; i = 4; while(i>0) i--; } void dsWait() { unsigned int i; while(ds); while(~ds); i = 4; while(i > 0) i--; } /******************************************/ //读取一位 /******************************************/ bit readBit() { unsigned int i; bit b; ds = 0; i++; ds = 1; i++; i++; b = ds; i = 8; while(i>0) i--; return b; } /******************************************/ //读取一个字节 /******************************************/ unsigned char readByte() { unsigned int i; unsigned char j, dat; dat = 0; for(i=0; i<8; i++) { j = readBit(); dat = (j << 7) | (dat >> 1); } return dat; } /******************************************/ //写入一个字节 /******************************************/ void writeByte(unsigned char dat) { unsigned int i; unsigned char j; bit b; for(j = 0; j < 8; j++) { b = dat & 0x01; dat >>= 1; if(b) { ds = 0; i++; i++; ds = 1; i = 8; while(i>0) i--; } else { ds = 0; i = 8; while(i>0) i--; ds = 1; i++; i++; } } } /******************************************/ //发送读取命令 /******************************************/ void sendChangeCmd() { dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0x44); } /******************************************/ //发送读取命令 /******************************************/ void sendReadCmd() { dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0xbe); } /******************************************/ //获取温度 扩大了10倍 /******************************************/ int getTmpValue() { unsigned int tmpvalue; int value; float t; unsigned char low, high; EA=0; sendChangeCmd();//ds18b20 EA=1; //delayMs(1000); EA=0; sendReadCmd(); low = readByte(); high = readByte(); EA=1; tmpvalue = high; tmpvalue <<= 8; tmpvalue |= low; value = tmpvalue; t = value * 0.0625; value = t * 10 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5 return value; }

lcd1602.h

c
#include <reg52.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* LCD_init(); LCD_write_str(1,1,"2223123"); */ sbit lcd_rs=P3^5; sbit lcd_rw=P3^6; sbit lcd_en=P3^4; #define DataPort P0 #define RS_CLR lcd_rs=0 #define RS_SET lcd_rs=1 #define RW_CLR lcd_rw=0 #define EN_CLR lcd_en=0 #define EN_SET lcd_en=1 void delay_lcd_ms(unsigned int a) { unsigned int i, j; for (i = a; i > 0; i--) for (j = 100; j > 0; j--) ; } //*********************************************************************** // 显示屏命令写入函数 //*********************************************************************** void LCD_write_com(unsigned char com) { RS_CLR; RW_CLR; EN_SET; DataPort = com; //命令写入端口 delay_lcd_ms(5); EN_CLR; } //*********************************************************************** // 显示屏数据写入函数 //*********************************************************************** void LCD_write_data(unsigned char dataa) { RS_SET; RW_CLR; EN_SET; DataPort = dataa; //数据写入端口 delay_lcd_ms(5); EN_CLR; } //*********************************************************************** // 显示屏字符串写入函数 //*********************************************************************** void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s) { if (y == 0) { LCD_write_com(0x80 + x); //第一行显示 } else { LCD_write_com(0xC0 + x); //第二行显示 } while (*s) { LCD_write_data( *s); s ++; } } //*********************************************************************** // 显示屏初始化函数 //*********************************************************************** void LCD_init(void) { LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x38); //显示模式设置 delay_lcd_ms(5); LCD_write_com(0x08); //显示关闭 delay_lcd_ms(5); LCD_write_com(0x01); //显示清屏 delay_lcd_ms(5); LCD_write_com(0x06); //显示光标移动设置 delay_lcd_ms(5); LCD_write_com(0x0C); //显示开及光标设置 delay_lcd_ms(5); }
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!