首页
游戏
影视
直播
广播
听书
音乐
图片
更多
看书
微视
主播
统计
友链
留言
关于
论坛
邮件
推荐
我的硬盘
我的搜索
我的记录
我的文件
我的图书
我的笔记
我的书签
我的微博
Search
1
在IC617中进行xa+vcs数模混仿
84 阅读
2
科普:Memory Compiler生成的Register file和SRAM有何区别?
74 阅读
3
virtuoso和empyrean alps模拟仿真和混仿教程
74 阅读
4
后仿中$setup,$hold与$setuphold
45 阅读
5
文档内容搜索哪家强? 15款文件搜索软件横向评测
36 阅读
默认分类
芯片市场
数字电路
芯片后端
模拟电路
芯片验证
原型与样片验证
算法与架构
DFX与量产封装
PC&Server OS设置
移动OS设置
软件方案
新浪备份
有道备份
登录
Search
标签搜索
python
Docker
vscode
linux
systemverilog
vcs
STM32
PyQT
EDA
FPGA
gvim
cadence
Alist
xilinx
UVM
uos
macos
package
MCU
risc-v
bennyhe
累计撰写
378
篇文章
累计收到
31
条评论
首页
栏目
默认分类
芯片市场
数字电路
芯片后端
模拟电路
芯片验证
原型与样片验证
算法与架构
DFX与量产封装
PC&Server OS设置
移动OS设置
软件方案
新浪备份
有道备份
页面
游戏
影视
直播
广播
听书
音乐
图片
看书
微视
主播
统计
友链
留言
关于
论坛
邮件
推荐
我的硬盘
我的搜索
我的记录
我的文件
我的图书
我的笔记
我的书签
我的微博
搜索到
378
篇与
的结果
2025-07-18
STM32 - 高级定时器的设定 - 基础-05 - 输出波形控制
The advanced-control timers (TIM1 and TIM8) can output two complementary(互补) signals and manage the switching-off and the switching-on instants of the outputs. This time is generally known as dead-time and it has to be adjust it depending on the devices connected to the outputs and their characteristics (intrinsic delays of level-shifters, delays due to power switches...)User can select the polarity of the outputs (main output OCx or complementary OCxN) independently for each output.This is done by writing to the CCxP and CCxNP bits in the TIMx_CCER register.TIMx_CCER 使能控制寄存器,控制CCxP 、CCxNP ,Bit 1 CC1P: Capture/Compare 1 output polarityCC1 channel configured as output:0: OC1 active high1: OC1 active lowBit 3 CC1NP: Capture/Compare 1 complementary output polarity0: OC1N active high.1: OC1N active low.The complementary signals OCx and OCxN are activated by a combination of several control bits:the CCxE and CCxNE bits in the TIMx_CCER registerOC/OCN输出使能控制Bit 0 CC1E: Capture/Compare 1 output enableCC1 channel configured as output:0: Off - OC1 is not active. OC1 level is then function of MOE, OSSI, OSSR, OIS1, OIS1N and CC1NE bits.1: On - OC1 signal is output on the corresponding output pin depending on MOE, OSSI, OSSR, OIS1, OIS1N and CC1NE bits.Bit 2 CC1NE: Capture/Compare 1 complementary output enable0: Off - OC1N is not active. OC1N level is then function of MOE, OSSI, OSSR, OIS1, OIS1N and CC1E bits.1: On - OC1N signal is output on the corresponding output pin depending on MOE, OSSI, OSSR, OIS1, OIS1N and CC1E bits.and the MOE, OISx, OISxN, OSSI and OSSR bits in the TIMx_BDTR TIM1 and TIM8 break and dead-time register (TIMx_BDTR)Bit 15 MOE: Main output enableThis bit is cleared asynchronously by hardware as soon as the break input is active. It is set by software or automatically depending on the AOE bit. It is acting only on the channels which are configured in output.0: OC and OCN outputs are disabled or forced to idle state.1: OC and OCN outputs are enabled if their respective enable bits are set (CCxE, CCxNE in TIMx_CCER register).See OC/OCN enable description for more details (Section 14.4.9: TIM1 and TIM8 capture/compare enable register (TIMx_CCER)).Bit 11 OSSR: Off-state selection for Run modeThis bit is used when MOE=1 on channels having a complementary output which are configured as outputs. OSSR is not implemented if no complementary output is implemented in the timer.See OC/OCN enable description for more details (Section 14.4.9: TIM1 and TIM8 capture/compare enable register (TIMx_CCER)).0: When inactive, OC/OCN outputs are disabled (OC/OCN enable output signal=0).1: When inactive, OC/OCN outputs are enabled with their inactive level as soon as CCxE=1or CCxNE=1. Then, OC/OCN enable output signal=1Bit 10 OSSI: Off-state selection for Idle modeThis bit is used when MOE=0 on channels configured as outputs.See OC/OCN enable description for more details (Section 14.4.9: TIM1 and TIM8 capture/compare enable register (TIMx_CCER)).0: When inactive, OC/OCN outputs are disabled (OC/OCN enable output signal=0).1: When inactive, OC/OCN outputs are forced first with their idle level as soon as CCxE=1 or CCxNE=1. OC/OCN enable output signal=1)Bits 7:0 DTG[7:0]: Dead-time generator setupThis bit-field defines the duration of the dead-time inserted between the complementary outputs. DT correspond to this duration.DTG[7:5]=0xx => DT=DTG[7:0]x tdtg with tdtg=tDTS.DTG[7:5]=10x => DT=(64+DTG[5:0])xtdtg with Tdtg=2xtDTS.DTG[7:5]=110 => DT=(32+DTG[4:0])xtdtg with Tdtg=8xtDTS.DTG[7:5]=111 => DT=(32+DTG[4:0])xtdtg with Tdtg=16xtDTS.Example if TDTS=125ns (8MHz), dead-time possible values are:0 to 15875 ns by 125 ns steps,16 us to 31750 ns by 250 ns steps,32 us to 63us by 1 us steps,64 us to 126 us by 2 us stepsand TIMx_CR2 registers.for more details. In particular, the dead-time is activated when switching to the IDLE state (MOE falling down to 0). Dead-time insertion is enabled by setting both CCxE and CCxNE bits, and the MOE bit if the break circuit is present. DTG[7:0] bits of the TIMx_BDTR register are used to control the dead-time generation for all channels.From a reference waveform OCxREF, it generates 2 outputs OCx and OCxN. If OCx and OCxN are active high:• The OCx output signal is the same as the reference signal except for the rising edge, which is delayed relative to the reference rising edge.(见下面分析)• The OCxN output signal is the opposite of the reference signal except for the rising edge, which is delayed relative to the reference falling edge.(见下面分析)If the delay is greater than the width of the active output (OCx or OCxN) then the corresponding pulse is not generated.The following figures show the relationships between the output signals of the dead-time generator and the reference signal OCxREF. (we suppose CCxP=0, CCxNP=0, MOE=1, CCxE=1 and CCxNE=1 in these examples)CC1P=0 ----> 0: OC1 active high CC1NP =0 ----> : 0: OC1N active high.MOE=1 ----> 1: OC and OCN outputs are enabledCCxE=1 ----> 1: On - OC1 signal is output on the corresponding output pin depending on MOE, OSSI, OSSR, OIS1, OIS1N and CC1NE bits.CCxNE=1 ----> 1: On - OC1N signal is output on the corresponding output pin depending on MOE, OSSI, OSSR, OIS1, OIS1N and CC1E bits.笔者案:我们现在依据上面的这个例子来分析一下:• The OCx output signal is the same as the reference signal except for the rising edge, which is delayed relative to the reference rising edge首先看OCX的输出,他应该是完全和OCXREF的输出一致,除了,上升沿会增加死区延时:蓝色为相同部分,后面上升沿往后移动了一格设定的delay时间。• The OCxN output signal is the opposite of the reference signal except for the rising edge, which is delayed relative to the reference falling edge.(见下面分析)The dead-time delay is the same for each of the channels and is programmable with the DTG bits in the TIMx_BDTR register.delay的时间通过DTG来控制。Re-directing OCxREF to OCx or OCxNIn output mode (forced, output compare or PWM), OCxREF can be re-directed to the OCx output or to OCxN output by configuring the CCxE and CCxNE bits in the TIMx_CCER register.将输出的OCXREF的波形可以转接到OCX 等其他端口,This allows the user to send a specific waveform (such as PWM or static active level) on one output while the complementary remains at its inactive level. Other possibilities are to have both outputs at inactive level or both outputs active and complementary with dead-time.Note: When only OCxN is enabled (CCxE=0, CCxNE=1), it is not complemented and becomes active as soon as OCxREF is high. For example, if CCxNP=0 then OCxN=OCxRef. On the other hand, when both OCx and OCxN are enabled CCxE=CCxNE=1) OCx becomes active when OCxREF is high whereas OCxN is complemented and becomes active whenOCxREF is low.有道云笔记2021-11-15 19:29:53
2025年07月18日
1 阅读
0 评论
0 点赞
2025-07-18
HyperBus Nor Flash小记
InterfaceMandatory I/O SummaryOptional I/O SummaryProtocal当HyperBus处于Idle状态(CK=Low & CK#=High)时,CS#从High变成Low,hyperbus的传输开始进行。最前面的三个时钟周期传输3个word的Command/Address(CA0, CA1, CA2),这三个word的CA用来决定这个传输一些特性。PS:这里面的word是2个byte,就是16bit。一个时钟周期是指两个clock,至于为什么这样定,我也不知道,Hyperbus的specification就是这么定的所以3个word的CA信息一共是48个bit。当传输完CA信息后,bus上需要传输一些dummy clock初始化RWDS信号。RWDS就是CK加了一些延迟的信号,用作高速读操作时的DQS。当数据传输开始,读数据是在RWDS的边沿进行采样,写数据是在Single-ended clock(即3.0V的CK)的边沿采样,或者在Differential clock(即1.8V CK和CK#)模式下,在CK和CK#交叉点进行数据采样。一旦完成数据传输,host就可以把CS#拉高并且把clock置为IDLE状态。当clock已经是IDLE状态了,拉嘎CS#就能结束一次传输。读时序下面贴出一个实际的读数据的时序, 读数据的地址是0x400。CA[48:0] = 0xA000004000。其中CA[47] = 1代表读,CA[46] = 0, CA[45] =1代表linear burst,ROW & Upper Column Address = 0x0000040 = 0x400 / 0x10, Lower Column Address=0x0 = 0x400 % 0x10。在插入了一些dummy的时钟周期后,进行了数据的采集。其中, 插入在CA和数据之间的dummy clock的个数是随设备不同而不同的,同时也跟Hyperbus的采样频率有关,这个需要参考不同的Hyberbus设备的手册才能知道。写时序写时序分为Write Transactions with Initial Latency和Write Transactions without Initial Latency。由于我并没有涉及太多的写设备的工作,所以这里就不多讲了。有Initial Latency的时序跟读时序差不多,只不过需要注意的是采样的时钟并不是RWDS即DQS,而是CK和CK#。而没有Initial Latency的就更简单了,直接数据就跟在CA后面,下面贴出官方Specification的是时序图。有道云笔记2021-11-08 11:34:45
2025年07月18日
4 阅读
0 评论
0 点赞
2025-07-18
用Tcl实现Vivado设计全流程
Vivado有两种工作模式:project模式和non-project模式。这两种模式都可以借助VivadoIDE或Tcl命令来运行。相比之下,VivadoIDE给project模式提供了更多的好处,而Tcl命令使得non-project模式运行起来更简单。在project模式下,Vivado会自动管理整个设计流程和文件数据。最直接的体现是在Vivado左侧导航Flow Navigator下会显示所有流程,从设计输入到最终生成bit文件。同时,Vivado会自动创建相应的文件目录,生成相应的文件例如dcp以及相应的报告。Non-project模式是一种内存编译流程。用户可以从指定位置读取文件到内存中,然后进行编译。可以逐步执行每个步骤如综合、布局、布线等,可以根据需求设定编译参数。这一切都可以通过Tcl命令完成。显然,non-project模式下,用户可以通过Tcl命令管理设计文件和设计流程,体现了该模式的主要优势即用户对设计流程有完全的掌控力。Project模式和non-project模式的主要区别如下图所示。不难看出,project模式下更多的管理、操作都是“自动”完成的;而non-project模式下,则是“手工”完成的。从Tcl命令的角度而言,project和non-project模式也是不同的,如下图所示。Project模式下用到的Tcl命令是一种打包的命令,例如添加设计文件需用add_files,文件可以是HDL(包括VHDL,Verilog或SystemVerilog),可以是约束文件(包括.xdc或.tcl),可以是网表文件(可以是dcp,ngc或edif)等。Implementation时,命令launch_runs就可以按照指定的策略完成所有的步骤,包括生成相应的DCP。Non-project模式下用到的Tcl命令是分立的,例如,读入设计文件,如果是VHDL,需要用到read_vhdl;如果是Verilog,需要用到read_verilog,如果是.xdc,需要用到read_xdc;如果是DCP,需要用到read_checkpoint;如果是EDIF,需要用到read_edif。而在implementation时,需要分别用到opt_design、place_design、phys_opt_design和route_design等。因为Tcl命令使得non-project模式更能简单地运行,这里我们将介绍如何通过Tcl命令在non-project模式下完成所有步骤。有道云笔记2021-11-04 16:41:15
2025年07月18日
1 阅读
0 评论
0 点赞
2025-07-18
Vscode自动生成verilog例化
前言veirlog模块例化的时候,辣么多的信号端子,手动例化又慢又容易出错,葵花妈妈开课啦,孩子手残老犯错怎么办?当然是脚本一劳永逸,妈妈再也不担心手残党。流程(1)在vscode中安装如下插件。(2)在电脑中安装python3以上的环境。下载地址:https://www.python.org/downloads/release/python-373/安装记得一定要勾选添加路径,记得管理员安装。重启你的电脑。在cmd窗口输入python即可验证是否安装成功!(3)安装chardet。为确保插件可用,这个需要安装。参考链接:https://blog.csdn.net/sinat_28631741/article/details/80483064方式一 源码按照: 第一步:下载压缩文件,例如: 'chardet-3.0.4.tar.gz'; 第二步:解压文件到python安装位置下的‘site-packages’目录下,例如:‘D:\python2.7\Lib\site-packages’; 第三步:打开终端命令窗口,进入解压的‘chardet’目录下,执行命令:python setup.py install (4)修改插件的原始py文件,觉得开发者的py有瑕疵,让帅气的同事重新整了个,把以下代码替换进原始py文件即可。在打开v文件的vscode下按ctrl+p,输入instance可出现下述界面。替换此py文件的代码即可。#! /usr/bin/env python ''' vTbgenerator.py -- generate verilog module Testbench generated bench file like this: fifo_sc #( .DATA_WIDTH ( 8 ), .ADDR_WIDTH ( 8 ) ) u_fifo_sc ( .CLK ( CLK ), .RST_N ( RST_N ), .RD_EN ( RD_EN ), .WR_EN ( WR_EN ), .DIN ( DIN [DATA_WIDTH-1 :0] ), .DOUT ( DOUT [DATA_WIDTH-1 :0] ), .EMPTY ( EMPTY ), .FULL ( FULL ) ); Usage: python vTbgenerator.py ModuleFileName.v ''' import random import re import sys from queue import Queue import chardet def delComment(Text): """ removed comment """ single_line_comment = re.compile(r"//(.*)$", re.MULTILINE) multi_line_comment = re.compile(r"/\*(.*?)\*/", re.DOTALL) Text = multi_line_comment.sub('\n', Text) Text = single_line_comment.sub('\n', Text) return Text def delBlock(Text): """ removed task and function block """ Text = re.sub(r'\Wtask\W[\W\w]*?\Wendtask\W', '\n', Text) Text = re.sub(r'\Wfunction\W[\W\w]*?\Wendfunction\W', '\n', Text) return Text def findName(inText): """ find module name and port list""" p = re.search(r'([a-zA-Z_][a-zA-Z_0-9]*)\s*', inText) mo_Name = p.group(0).strip() return mo_Name def paraDeclare(inText, portArr): """ find parameter declare """ pat = r'\s' + portArr + r'\s[\w\W]*?[;,)]' ParaList = re.findall(pat, inText) return ParaList def portDeclare(inText, portArr): """find port declare, Syntax: input [ net_type ] [ signed ] [ range ] list_of_port_identifiers return list as : (port, [range]) """ port_definition = re.compile( r'\b' + portArr + r''' (\s+(wire|reg|logic|interface)\s+)* (\s*signed\s+)* (\s*\[.*?:.*?\]\s*)* (?P<port_list>.*?) (?= \binput\b | \boutput\b | \binout\b | ; | \) ) ''', re.VERBOSE | re.MULTILINE | re.DOTALL ) pList = port_definition.findall(inText) t = [] for ls in pList: if len(ls) >= 2: t = t + portDic(ls[-2:]) return t def portDic(port): """delet as : input a =c &d; return list as : (port, [range]) """ pRe = re.compile(r'(.*?)\s*=.*', re.DOTALL) pRange = port[0] pList = port[1].split(',') pList = [i.strip() for i in pList if i.strip() != ''] pList = [(pRe.sub(r'\1', p), pRange.strip()) for p in pList] return pList def formatPort(AllPortList, isPortRange=1): PortList = AllPortList str = '' if PortList != []: l1 = max([len(i[0]) for i in PortList])+2 l3 = max(18, l1) strList = [] str = ',\n'.join([' ' * 4 + '.' + i[0].ljust(l3) + '(' + (i[0]) + ')' for i in AllPortList]) strList = strList + [str] str = ',\n\n'.join(strList) return str def formatDeclare(PortList, portArr, initial=""): str = '' if PortList != []: str = '\n'.join([portArr.ljust(4) + ' '+(i[1]+min(len(i[1]), 1)*' ' + i[0]) + ';' for i in PortList]) return str def formatPara(ParaList): paraDec = '' paraDef = '' if ParaList != []: s = '\n'.join(ParaList) pat = r'([a-zA-Z_][a-zA-Z_0-9]*)\s*=\s*([\w\W]*?)\s*[;,)]' p = re.findall(pat, s) l1 = max([len(i[0]) for i in p]) l2 = max([len(i[1]) for i in p]) paraDec = '\n'.join(['parameter %s = %s;' % (i[0].ljust(l1 + 1), i[1].ljust(l2)) for i in p]) paraDef = '#(\n' + ',\n'.join([' .' + i[0].ljust(l1 + 1) + '( ' + i[1].ljust(l2)+' )' for i in p]) + ')\n' return paraDec, paraDef def portT(inText, ioPadAttr): x = {} count_list = [] order_list = [] for i in ioPadAttr: p = port_index_list(inText, i) for j in p: count_list.append(j) x[j] = i count_list = quick_sort(count_list, 0, len(count_list)-1) for c in count_list: order_list.append(x.get(c)) return order_list def quick_sort(myList, start, end): if start < end: i, j = start, end base = myList[i] while i < j: while (i < j) and (myList[j] >= base): j = j - 1 myList[i] = myList[j] while (i < j) and (myList[i] <= base): i = i + 1 myList[j] = myList[i] myList[i] = base quick_sort(myList, start, i - 1) quick_sort(myList, j + 1, end) return myList def formatPort_order(padAttr, orderList): for p in padAttr: q = Queue() for i in padAttr.get(p): q.put(i) padAttr[p] = q AllPortList = [] for o in orderList: AllPortList.append(padAttr.get(o).get()) return AllPortList def port_index_list(intext, text): l = [] t = intext index = t.find(text) while index > -1: t = t.replace(text, random_str(len(text)), 1) l.append(index) index = t.find(text) return l def random_str(size): s = '' for i in range(size): s += str(random.randint(0, 9)) return s def getPortMap(AllPortList, ioPadAttr): if len(AllPortList) != len(ioPadAttr): return p_map = {} for i in range(len(AllPortList)): p_map[ioPadAttr[i]] = AllPortList[i] return p_map def writeTestBench(input_file): """ write testbench to file """ with open(input_file, 'rb') as f: f_info = chardet.detect(f.read()) f_encoding = f_info['encoding'] with open(input_file, encoding=f_encoding) as inFile: inText = inFile.read() # removed comment,task,function inText = delComment(inText) inText = delBlock(inText) # moduel ... endmodule # moPos_begin = re.search(r'(\b|^)module\b', inText).end() moPos_end = re.search(r'\bendmodule\b', inText).start() inText = inText[moPos_begin:moPos_end] name = findName(inText) paraList = paraDeclare(inText, 'parameter') paraDec, paraDef = formatPara(paraList) ioPadAttr = ['input', 'output', 'inout','interface'] orlder = portT(inText, ioPadAttr) input = portDeclare(inText, ioPadAttr[0]) output = portDeclare(inText, ioPadAttr[1]) inout = portDeclare(inText, ioPadAttr[2]) interface = portDeclare(inText, ioPadAttr[3]) portList = formatPort(formatPort_order( getPortMap([input, output, inout,interface], ioPadAttr), orlder)) input = formatDeclare(input, 'reg') output = formatDeclare(output, 'wire') inout = formatDeclare(inout, 'wire') interface = formatDeclare(interface, 'wire') # write Instance # module_parameter_port_list if(paraDec != ''): print("// %s Parameters\n%s\n" % (name, paraDec)) # list_of_port_declarations #print("// %s Inputs\n%s\n" % (name, input)) #print("// %s Outputs\n%s\n" % (name, output)) #if(inout != ''): # print("// %s Bidirs\n%s\n" % (name, inout)) print("\n") # UUT print("%s %s inst_%s (\n%s\n);" % (name, paraDef, name, portList)) if __name__ == '__main__': writeTestBench(sys.argv[1])(5)享受一下吧。比如我们有如下代码:crtl+p,输入instance,按回车即可。 复制粘贴大发好。以上。转载于:https://www.cnblogs.com/kingstacker/p/9944259.html有道云笔记2021-11-02 11:37:58
2025年07月18日
8 阅读
0 评论
0 点赞
2025-07-18
STM32之霍尔传感器模块
一、简介本文介绍如何在STM32上使用霍尔传感器模块。二、实验平台库版本:STM32F10x_StdPeriph_Lib_V3.5.0编译软件:MDK4.53硬件平台:STM32开发板(主芯片stm32f103c8t6)仿真器:JLINK三、版权声明博主:甜甜的大香瓜声明:喝水不忘挖井人,转载请注明出处。原文地址:http://blog.csdn.NET/feilusia联系方式:897503845@qq.com香瓜BLE之CC2541群:127442605香瓜BLE之CC2640群:557278427香瓜BLE之Android群:541462902香瓜单片机之STM8/STM32群:164311667甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i四、实验前提1、在进行本文步骤前,请先阅读以下博文:暂无2、在进行本文步骤前,请先 实现以下博文:暂无五、基础知识1、霍尔传感器是什么?答:霍尔传感器是根据霍尔效应制作的一种磁场传感器。用磁铁去靠近霍尔传感器时,霍尔传感器的引脚电平会产生变化。2、霍尔传感器主要用在什么地方?答:霍尔传感器可测速、计数、限位上。举例限位功能:两个霍尔传感器形成45°的夹角,电机边缘粘着一个磁铁,一旦电机转动导致磁铁触发任意其中一个霍尔传感器,则STM32检测到触发后立刻停止电机,不能再继续往此方向转动。以此达到限制电机转动角度的作用。3、本文使用的是什么霍尔传感器模块?答:香瓜买的霍尔传感器模块一共有四个引脚,GND、VCC、D0、A0。其中只需要用到三根线,GND、VCC、D0。(A0不知做啥用的,计数?)使用方法:1)5V供电。2)用跳线连接D0和STM32的IO口(本文连接的是PA11)。3)D0默认是高电平,但磁铁的特定一面(磁铁另一面无用)去靠近霍尔传感器模块时,D0会被拉低。4、霍尔传感器与限位开关有什么区别?答:1)限位开关①优点:无功耗。②缺点:易损坏。2)霍尔传感器①优点:不易损坏。②缺点:有功耗。六、实验步骤1、编写并添加霍尔传感器驱动1)编写驱动GUA_Hall_Sensor.c(存放在“……\HARDWARE”) //****************************************************************************** //name: GUA_Hall_Sensor.c //introduce: 霍尔传感器驱动 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2017.03.06 //****************************************************************************** #include"stm32f10x.h" #include"GUA_Hall_Sensor.h" /*********************宏定义************************/ //霍尔传感器引脚 #define GUA_HALL_SENSOR_PORT GPIOA #define GUA_HALL_SENSOR_PIN GPIO_Pin_11 //消抖总次数 #define GUA_HALL_SENSOR_DISAPPERAS_SHAKS_COUNT 500000 /*********************内部变量************************/ static GUA_U32 sGUA_Hall_Sensor_DisapperasShakes_IdleCount = 0; //消抖时的空闲状态计数值 static GUA_U32 sGUA_Hall_Sensor_DisapperasShakes_TriggerCount = 0; //消抖时的触发状态计数值 /*********************内部函数************************/ staticvoidGUA_Hall_Sensor_IO_Init(void); //****************************************************************************** //name: GUA_Hall_Sensor_IO_Init //introduce: 霍尔传感器的IO初始化 //parameter: none //return: none //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2017.03.06 //****************************************************************************** staticvoidGUA_Hall_Sensor_IO_Init(void) { //IO结构体 GPIO_InitTypeDef GPIO_InitStructure; //时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //霍尔IO配置 GPIO_InitStructure.GPIO_Pin = GUA_HALL_SENSOR_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GUA_HALL_SENSOR_PORT, &GPIO_InitStructure); } //****************************************************************************** //name: GUA_Hall_Sensor_Check_Pin //introduce: 霍尔传感器检测触发状态 //parameter: none //return: GUA_HALL_SENSOR_STATUS_IDLE or GUA_HALL_SENSOR_STATUS_TRIGGER //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2017.03.06 //****************************************************************************** GUA_U8 GUA_Hall_Sensor_Check_Pin(void) { //没触发 if(GPIO_ReadInputDataBit(GUA_HALL_SENSOR_PORT, GUA_HALL_SENSOR_PIN) == SET) { //计数 sGUA_Hall_Sensor_DisapperasShakes_IdleCount++; sGUA_Hall_Sensor_DisapperasShakes_TriggerCount = 0; //判断计数是否足够 if(sGUA_Hall_Sensor_DisapperasShakes_IdleCount >= GUA_HALL_SENSOR_DISAPPERAS_SHAKS_COUNT) { return GUA_HALL_SENSOR_STATUS_IDLE; } } //触发 else { //计数 sGUA_Hall_Sensor_DisapperasShakes_IdleCount = 0; sGUA_Hall_Sensor_DisapperasShakes_TriggerCount++; //判断计数是否足够 if(sGUA_Hall_Sensor_DisapperasShakes_TriggerCount >= GUA_HALL_SENSOR_DISAPPERAS_SHAKS_COUNT) { return GUA_HALL_SENSOR_STATUS_TRIGGER; } } return GUA_HALL_SENSOR_STATUS_DISAPPERAS_SHAKS; } //****************************************************************************** //name: GUA_Limit_Switch_Init //introduce: 霍尔传感器初始化 //parameter: none //return: none //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2017.03.06 //****************************************************************************** voidGUA_Hall_Sensor_Init(void) { //初始化IO GUA_Hall_Sensor_IO_Init(); } 2)编写驱动头文件GUA_Hall_Sensor.h(存放在“……\HARDWARE”) //****************************************************************************** //name: GUA_Hall_Sensor.h //introduce: 霍尔传感器驱动的头文件 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2017.03.06 //****************************************************************************** #ifndef _GUA_HALL_SENSOR_H_ #define _GUA_HALL_SENSOR_H_ /*********************宏定义************************/ //类型宏 #ifndef GUA_U8 typedefunsignedchar GUA_U8; #endif #ifndef GUA_8 typedefsignedchar GUA_8; #endif #ifndef GUA_U16 typedefunsignedshort GUA_U16; #endif #ifndef GUA_16 typedefsignedshort GUA_16; #endif #ifndef GUA_U32 typedefunsignedlong GUA_U32; #endif #ifndef GUA_32 typedefsignedlong GUA_32; #endif #ifndef GUA_U64 typedefunsignedlonglong GUA_U64; #endif #ifndef GUA_64 typedefsignedlonglong GUA_64; #endif //霍尔传感器的触发状态 #define GUA_HALL_SENSOR_STATUS_TRIGGER 0 //霍尔传感器触发 #define GUA_HALL_SENSOR_STATUS_IDLE 1 //霍尔传感器没触发 #define GUA_HALL_SENSOR_STATUS_DISAPPERAS_SHAKS 2 //霍尔传感器消抖中 /*********************外部函数声明************************/ GUA_U8 GUA_Hall_Sensor_Check_Pin(void); voidGUA_Hall_Sensor_Init(void); #endif 3)工程中添加GUA_Hall_Sensor.c4)在MDK设置中添加串口驱动源文件路径2、在应用层中调用1)添加驱动头文件(main.c中)#include"GUA_Hall_Sensor.h"2)添加驱动初始化代码(main.c的main函数中)//霍尔传感器初始化GUA_Hall_Sensor_Init(); 3)添加测试代码①写测试代码(main.c中) staticvoidGUA_Test(void) { U8 nGUA_Ret = 0; U8 nGUA_Stop = 0; while(1) { //检测霍尔当前状态 nGUA_Ret = GUA_Hall_Sensor_Check_Pin(); //检测到霍尔被触发 if(nGUA_Ret == GUA_HALL_SENSOR_STATUS_TRIGGER) { nGUA_Stop = 1; } } ②调用测试代码(main.c的main函数中)//测试代码GUA_Test();七、注意事项暂无。八、实验结果仿真并设置断点在测试代码的“nGUA_Stop = 1;”中,全速运行。用磁铁去靠近模块上的霍尔传感器芯片,模块上的led被点亮表示触发,同时工程中消抖之后会停止在断点处,表示检测到PA11处的霍尔传感器触发导致的低电平。如下图因此实验成功。有道云笔记2021-11-16 17:25:02
2025年07月18日
0 阅读
0 评论
0 点赞
1
...
21
22
23
...
76