说明:在哔哩哔哩跟随UP主铁头山羊学习,所有代码均来自铁头山羊B站课堂或者根据铁头山羊代码修改。
利用TM1640芯片,串行通信方式,STM3两个GPIO进行通信。
1、 两个GPIO进行通信,GPIOA_PIN–DIN;GPIOA_PIN1—CLK。
2、 通信方式主要是串行通信方式,通信方式软件编写:
读懂时序图,包括起始位、数据位、结束位。
在输入数据时当CLK是高电平时,DIN上的信号必须保持不变;只有CLK上的时钟信号为低电平时,DIN上的信号才能改变。数据的输入总是低位在前,高位在后传输。
数据输入的开始条件是CLK为高电平时,DIN由高变低。
结束条件是CLK为高时,DIN由低电平变为高电平。
波形时长根据时序特性来延时,本次编程使用1us。


3、 显示数据包括三个命令,其中command2中的data最多有16个,即可以同时显示16个数码管,如图

4、 command1:主要设置数据命令,本次设置为地址自动加1模式。

5、 command2:主要设置地址,以及导入显示数据。

6、 command3:主要设置显示亮度。

7、 数码管原理图连接。

TM1640通信电平位5V,单片机IO电平为3.3V,所以需要外接上拉到5V,采用开漏模式。
//TM1640初始化
void TM1640_Init()
{
//GPIOA_PIN_0--Data; GPIOA_PIN_1--Clk 开漏模式
GPIO_InitTypeDef gpioinit;
gpioinit.Pin = GPIO_PIN_0 | GPIO_PIN_1;
gpioinit.Mode = GPIO_MODE_OUTPUT_OD;
gpioinit.Speed = GPIO_SPEED_FREQ_HIGH;
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA,&gpioinit);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_SET);
}
精确到1us。
//延时函数,最小1us
void Delayus(uint32_t us)
{
uint32_t n = SystemCoreClock / 1000000 / 8 * us;
do{
__NOP();
}while(n--);
}
阅读时序图,将命令发送写成函数,在发不同命令时可以直接调用。主要运用指针指向不同地址的数据,比较方便。
//TM1640数据发送框架,按起始位、数据位、结束位
void TM1640_SendFrame(uint8_t *pData, uint32_t Len)
{
uint32_t i,j;
// send Start Flag
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
Delayus(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
Delayus(1);
// send Command or Data
for(i=0; i<Len; i++)
{
for(j=0; j<8; j++)
{
if((pData[i] & (0x01 << j)) != 0)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
}
Delayus(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
Delayus(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
Delayus(1);
}
}
// send End Flag
//Delayus(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
Delayus(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
}
主要建立一个数组buffer,用来填写数据的值。灵活应用这个判断数据是1or0: if((pData[i] & (0x01 << j)) != 0)
//发送命令一
void TM1640_SendCommand1(uint8_t AddrMode)
{
uint8_t buffer[1];
buffer[0] = AddrMode;
TM1640_SendFrame(buffer,1);
}
主要数据多达16个,并且先要填写初始地址,所以要发送的数据最多17个,所以建立数组时元素要有17个。
//发送命令二
void TM1640_SendCommand2(uint8_t Addr, uint8_t *pData, uint32_t Len)
{
uint32_t i;
uint8_t buffer[17];
buffer[0] = 0xc0 | Addr;
//TM1640_SendFrame(buffer,1);
for(i=0; i<Len; i++)
{
buffer[i+1] = pData[i];
}
TM1640_SendFrame(buffer, Len+1);
}
与command1函数差不多。
//发送命令三
void TM1640_SendCommand3(uint8_t PulseWidth)
{
uint8_t buffer[1];
buffer[0] = PulseWidth;
TM1640_SendFrame(buffer,1);
}
主要利用取余原理,从低位往高位显示。
//数码管显示函数
void SEG_Display(uint32_t Num)
{
uint8_t i;
uint8_t pData[8];
const uint32_t SEG_Number[10] =
{
//共阴数码管
// 0 1 2 3 4 5 6 7 8 9
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};
for(i=0; i<8; i++)
{
pData[7-i] = SEG_Number[Num % 10];
Num /= 10;
}
TM1640_SendCommand1(TM1640_AddrMode_AutoInc);
TM1640_SendCommand2(0x00, pData, 8);
TM1640_SendCommand3(TM1640_PulseWidth_1_16);
}
主要counter计数,一秒加1。
int main()
{
HAL_Init();
TM1640_Init();
while(1)
{
SEG_Display(counter);
HAL_Delay(1000);
counter++;
HAL_Delay(1);
}
}
尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
注意:本文主要掌握DCN自研无线产品的基本配置方法和注意事项,能够进行一般的项目实施、调试与运维AP基本配置命令AP登录用户名和密码均为:adminAP默认IP地址为:192.168.1.10AP默认情况下DHCP开启AP静态地址配置:setmanagementstatic-ip192.168.10.1AP开启/关闭DHCP功能:setmanagementdhcp-statusup/downAP设置默认网关:setstatic-ip-routegeteway192.168.10.254查看AP基本信息:getsystemgetmanagementgetmanaged-apgetrouteAP配
我有一个数组:array=['Footballs','Baseball','football','Soccer']而且我需要计算看到Football或Baseball的次数,无论大小写和复数形式如何。这是我尝试做的,但没有成功:array.count{|x|x.downcase.include?'football'||x.downcase.include?'baseball'}编写这段代码的正确或更好的方法是什么?我正在寻找3作为答案。 最佳答案 我会将count与一个block结合使用,该block根据与您正在寻找的约束相匹配的正
在TextMateRVMinstructions它说将TM_RUBY设置为/Users/wayne/.rvm/bin/textmate_ruby并在theimage中的文本它显示它设置为rvm-auto-ruby。我决定将它设置为rvm-auto-ruby以为它会使用RVM的默认Ruby版本。在TM_RUBY设置为rvm-auto-ruby的RSpec.bundle中运行CommandR将导致loaderror.当您将它设置为textmate_ruby时,它会起作用。这里唯一的问题是TextMate并不总是使用默认版本的Ruby,因为它是硬编码在该文件中的。/Users/jspoone
LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L
我正在为在AmazonEC2实例上运行的应用程序设计一个AutoScaling系统。应用程序从SQS读取消息并对其进行处理。AutoScaling系统将监控两件事:SQS中的消息数量,所有EC2机器上运行的进程总数。例如,如果SQS中的消息数量超过3000,我希望系统自动缩放,创建一个新的EC2实例,在其上部署代码,当消息数量低于2000时,我希望系统终止EC2实例.我正在用Ruby和Capistrano做这件事。我的问题是:我无法找到一种方法来确定在所有EC2机器上运行的进程数并将该数字保存在变量中。你能帮帮我吗? 最佳答案 您可
我有以下工厂:FactoryGirl.definedofactory:foodosequence(:name){|n|"Foo#{n}"}trait:ydosequence(:name){|n|"Fooy#{n}"}endendend如果我跑create:foocreate:foocreate:foo,:y我得到Foo1,Foo2,Fooy1。但我想要Foo1,Foo2,Fooy3。我怎样才能做到这一点? 最佳答案 经过smile2day'sanswer的一些提示后和thisanswer,我得出以下解决方案:FactoryGirl.
简单地说,我如何使用Sequel执行此查询?selecta.id,count(t.id)fromalbumsarightjointrackstont.album_id=a.idgroupbya.id 最佳答案 DB[:albums___a].right_join(:tracks___t,:album_id=>:id).select_group(:a__id).select_more{count(:t__id)} 关于ruby-续集:如何使用分组和计数,我们在StackOverflow上找