520了,用32做个简单的小程序 程序员的数学--用贝叶斯定理来推断一个案子 文旅部新规:在线旅游网站不得擅自屏蔽删除评价 不得大数据杀熟 苏宁易购开学季消费大数据:手机以旧换新销量增长299% 做实供电服务“133” 助大数据直上“云”端 思科前程序员离职 5 月后“删虚拟机跑路”,240 万美元打水漂,网友:够狠! 抗疫代码成国博最新藏品 阿里程序员“写代码写进国博挺酷” 国博史上首次收藏代码!它们是阿里程序员写下的抗疫代码 威胜信息发布2020年上半年业绩:物联网产业进入爆发期 营收净利双增长 下月发布会不止有新品折叠屏手机 酷开的物联网家居生态野心初现 史上最全的数据库面试题 数据库面试必看 一个数据库SQL查询的数次轮回 百度智能云正式对外发布百度智能云数据库品牌GaiaDB 数据库三大泛式是什么 电力行业网管需求 IT运维管理解决方案 citrix桌面虚拟化中的运维工具Director SRE运维体系的构建和工作职责划分 运维的核心价值是什么 手游开发定制的全过程详解 开发人员透露:《赛博朋克2077》枪支泛滥 成熟的产品经理如何应对“这个需求不合理” CI/CD管道对开发和运维的重要性 APP开发的流程是怎样的 如何开发一个APP 零基础学web前端开发要学多久 如何系统学习 Web前端要学习哪些内容呢 前端工程师至少要满足四类客户的需求 前端学习计划思维导图 前端人如何选择自己的技术栈 前端人如何更快地成长 大数据的七大核心具体价值 核心价值究其用户到底是谁 大数据核心技术是什么 该怎么掌握Hadoop知识 未来大数据应用场景广阔 中国将成为全球最大的数据圈 2020大数据产业生态大会通过“现场论道+云端连线”全程直播的方式在北京举行 2020中国大数据生态产业大会 华为云大数据连续四年荣登50强榜首 中国电信全面提速大数据新基建 无法启动计算机时该怎么办 通过这6个专业技巧来加速计算机 计算机专家提供在家工作或学习的技巧 2020年空中数据计算机市场新战略报告:技术进步,趋势与增长 物联网分析市场前景2020-2025年最新发展数据和市场趋势预测 马来西亚主要供应商的物联网(IoT)安全市场规模和增长 2020年医疗保健行业的物联网(IoT)市场分析以及到2025年的未来需求 零售市场类型和应用中的物联网(IoT)展望和2025年预测 蒙特利尔华纳兄弟公司正在寻找新程序员 而工作就是玩家的天堂 世界各地的5位著名女程序员 代码中的AI:AI对开发人员做了什么 如何找到程序员的第一份工作 盲人程序员创建没有图形的手机游戏 花费不到30美元 即可成为拥有30小时教程的专家Python程序员
您的位置:首页 >大数据 >

520了,用32做个简单的小程序

520到了,看着朋友圈里的花式秀恩爱,平常午餐最爱吃的泡面都变得不那么香了。于是!突发奇想,突然就来了更新的想法,今天用32来做一个非常简单的小程序:

简单放个歌,再放个图

stm32f103c8t6无源蜂鸣器库函数void Bee_Init(void)void Bee_test(void)乐谱(简谱)void Play_Music(void)OLED模块(7脚64*128)模拟SPI.h.cOLED.h.c显示16*16的字符字符/图片库,取模

stm32f103c8t6

因为基本只用到两个外设,程序容量也很小,所以用c8t6就刚刚好
在这里插入图片描述

无源蜂鸣器

这里要用的是无源蜂鸣器,其音调是可调的。

库函数

我们先声明要用到的引脚以及相应的函数:

#define BeeGpioGPIO自选#define Bee GPIO_Pin_自选void Bee_Init(void); //蜂鸣器初始化void Bee_test(void); //蜂鸣器测试void Play_Music(void);//播放音乐

void Bee_Init(void)

这个也非常好理解,和初始化引脚是一样的 。

void Bee_Init(void){GPIO_InitTypeDefGPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = Bee; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(BeeGpio, &GPIO_InitStructure);GPIO_WriteBit(BeeGpio,Bee,(BitAction)(1)); }

void Bee_test(void)

在主函数演奏之前,我们先测试一下蜂鸣器好不好使,让它先响一声:

void Bee_test(void){ u16 i;for(i=0;i<200;i++){GPIO_WriteBit(BeeGpio,Bee,(BitAction)(0));delay_us(500); GPIO_WriteBit(BeeGpio,Bee,(BitAction)(1));delay_us(500);}}

为了给下文的演奏做铺垫,发出声响的原理现在要着重强调一下:
(delay函数是已经写好的,有us、ms、s等等单位,这里用的是us)

在这个for循环里,先后两次的delay_us(500)加在一起构成了一个周期,这个周期的时间长是1000us,也就是1ms。在这1ms的时间里,一半的时间蜂鸣器不响,另一半的时间响,如此重复200次,就成为了我们人类耳朵听到的一个时间约为200ms的响声。

乐谱(简谱)

以一个非常简单的粉刷匠为例:(希望我没有记错谱子哈哈哈)
在这里插入图片描述

C调中音12345对应的声音频率分别是:523、587、659、698、784Hz。所以我们就可以把简谱中的数字依次替换(C调其他音对应频率见文末注脚1)每个音都是要持续一定时间的,以ms为单位,比如“2432”的声音要保持一致,而“5-”要持续略长的时间

以“2432|5-”为例,我们把音调与对应的时间 两两一组,放到一个数组里:

uc16 m_24325[10]={//奇数项为频率,偶数项为持续时间(ms)587,300,698,300,659,300,587,300,784,750,};

我在测试的时候发现如果严格按照音调对应频率的话,听起来反而与想象中的音乐差了不少(难道是蜂鸣器的事?)所以稍微改了一下频率。

void Play_Music(void)

 void Play_Music(void){ u16 i,j;for(i=0;i<5;i++){for(j=0;j<m_24325[i*2]*m_24325[i*2+1]/1000;j++){GPIO_WriteBit(BeeGpio,Bee,(BitAction)(0));delay_us(500000/m_24325[i*2]);GPIO_WriteBit(BeeGpio,Bee,(BitAction)(1)); delay_us(500000/m_24325[i*2]); }}}
因为在前文的乐谱中,记了10个数据,5对音调与时间,所以令i=0;i<5在第二个for循环中,先后两次delay_us(500000/music1[i*2]),使得周期变为1000 000/频率而 j<m_24325[i*2]m_24325[i2+1]/1000 和 周期共同决定了蜂鸣器发出这个频率对应音调的时间

演算一下:以“523Hz”响750ms为例:
在这里插入图片描述
如此,我们便能演奏一些基本的曲子了,只需要自己写一个乐谱就好了。
void Play_Music(void)也可以写为有输入参数的函数,这样便于我们用同一个函数调用不同的乐谱。

接下来就到了另一个模块:

OLED模块(7脚64*128)

买到OLED模块以后,商家往往都会附赠配套程序的,不过往往都会赠IIC的程序。这里把我以前用的SPI程序放上。

模拟SPI

.h

#define OLED_CMD 0 #define OLED_DATA 1 #define OLED_CLKPAout(4)#define OLED_MOSI PAout(3) #define OLED_RSTPAout(2) #define OLED_DC PAout(1)void OLED_SPI_Init(void); void SPI_WriteByte(uint8_t addr,uint8_t data); void WriteCmd(unsigned char cmd); void WriteData(unsigned char data); 

.c

void OLED_SPI_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);}void SPI_WriteByte(unsigned char data,unsigned char cmd){unsigned char i=0;OLED_DC =cmd;OLED_CLK=0;for(i=0;i<8;i++){OLED_CLK=0;if(data&0x80)OLED_MOSI=1; else OLED_MOSI=0;OLED_CLK=1;data<<=1;}OLED_CLK=1;OLED_DC=1;}void WriteCmd(unsigned char cmd){SPI_WriteByte(cmd,OLED_CMD);}void WriteData(unsigned char data){SPI_WriteByte(data,OLED_DATA);}

OLED

.h

void OLED_Init(void);void OLED_ON(void);void OLED_OFF(void);void OLED_Refresh_Gram(void);void OLED_Clear(void);

.c

u8 OLED_GRAM[128][8]; void OLED_DLY_ms(unsigned int ms){ unsigned int a;while(ms){a=1335;while(a--);ms--;}}void OLED_Init(void){OLED_SPI_Init();OLED_CLK = 1;OLED_RST = 0;OLED_DLY_ms(100);OLED_RST = 1;WriteCmd(0xae);WriteCmd(0x00);WriteCmd(0x10);WriteCmd(0xd5);WriteCmd(0x80);WriteCmd(0xa8);WriteCmd(0x3f);WriteCmd(0xd3);WriteCmd(0x00);WriteCmd(0xB0);WriteCmd(0x40);WriteCmd(0x8d);WriteCmd(0x14);WriteCmd(0xa1);WriteCmd(0xc8);WriteCmd(0xda);WriteCmd(0x12);WriteCmd(0x81);WriteCmd(0xff);WriteCmd(0xd9);WriteCmd(0xf1);WriteCmd(0xdb);WriteCmd(0x30);WriteCmd(0x20);WriteCmd(0x00);WriteCmd(0xa4);WriteCmd(0xa6);WriteCmd(0xaf); OLED_Clear(); }void OLED_Refresh_Gram(void){u8 i,n; for(i=0;i<8;i++){WriteCmd(0xb0+i); WriteCmd(0x00);WriteCmd(0x10);for(n=0;n<128;n++)WriteData(OLED_GRAM[n][i]); } }void OLED_Clear(void){ u8 j,t;for(t=0xB0;t<0xB8;t++){ WriteCmd(t); WriteCmd(0x10); WriteCmd(0x00);for(j=0;j<132;j++){ WriteData(0x11); }}}

显示16*16的字符

这个是仿照商家的IIC例程改成SPI的写法,其实驱动OLED的方法都是一样的,只不过IIC和SPI略有不同而已(3个输入参数会在稍后讲到)

void OLED_DISPLAY_16x16(u8 x,u8 y, u16 w){ u8 j,t,c=0;y=y-14;for(t=0;t<2;t++){WriteCmd(0xb0+x); WriteCmd(y/16+0x10); WriteCmd(y%16);for(j=0;j<16;j++){ WriteData(M_16[(w*32)+c]);c++;}x++;}WriteCmd(0xAF); }
第一个参数x:字符的行:0、2、4、6共4行(4*16=64,把64个像素分为4行)第二个参数y:字符的列:共128列(像素),但是因为字符是16*16的,所以用n * 16代替,便于计算第三个参数w:对应库中的第几个字符库:M_16(在倒数第5行),这个内容马上就讲到

比如:OLED_DISPLAY_16x16(4,8*16,8),在OLED屏幕第3行的第8列,显示库中的第9个字符

字符/图片库,取模

这个库是需要咱们自己建立的,可以由取模软件自动生成每个字符对应的16进制数据。
我们用到的取模软件是:PCtoLCD2002
配置如图:
在这里插入图片描述
用它生成数据以后就可以把数据放到一个单独的.h文件中,作为我们自己的字符库。这里以两个16*16的空白为例

uc8 M_16[] = {//" "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};

这个软件还是很好用的,而且像素也可以自定,比如用64 * 128的图片铺满oled等等。详见生日快乐(b站投稿)。这里用的就是杜洋老师的开发板,我最初学32的时候就是学习杜洋老师的教程,虽然后来我又学了野火的32,正点原子的linux…(我很专一的/doge)

跑题了,这里只是举了一个16 * 16字符的例子,还有8 * 16字符、字符串、64 * 128图片等等,就请各位自己研究了/doge


我是康,希望做一名能帮助到各位的博主! 我不是本来要更机器学习的嘛? 在做了在做了(0%)预计下周会发布,欢迎感兴趣的小伙伴与我共同学习,一起进步!


C调低音频率(Hz)C调中音频率(Hz)C调高音频率(Hz)12621523110461#2771#5541#110922942587211752#3112#6222#1245333036593131843494698413974#3704#7404#148053925784515685#4155#8315#166164406880617606#4666#9326#18657494798871976

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。