一、 项目介绍
PIC16F13145采用高性能8位PIC核心架构,最高运行频率 32 MHz,配备 14 KB Flash程序存储器和 1KB RAM,还集成了极具特色的可配置逻辑块 (CLB) 模块,可独立于 CPU 运行,实现硬件级并行处理,包含32个基本逻辑元件阵列,支持多种逻辑功能配置,每个逻辑元件都能模拟 AND/OR/NAND/NOR 逻辑门、缓冲器/反相缓冲器、D 触发器、JK 触发器、多路复用器或四输入 LUT,可用于实现自定义电路、减轻CPU负担,提高系统响应速度。
项目目标:
- 使用片内的CLB功能实现按钮检测,并锁定结果或复位。
- 使用片内的CLB功能实现控制数码管显示数字。
- 生成随机数用于随机时间复位,并进入下一轮抢答状态。
二、设计思路
任务二:多路抢答器
CLB 输入边沿检测触发抢答或复位,触发后锁存抢答结果,并将结果通过 LUT 将结果显示在数码管上;触发复位后随机延时清除锁存器,再进入下一轮抢答;随机延时种子通过 adc 获得,再通过随机数生成函数获得随机数用于延时。
软件流程图:
CLB 模块 配置
主程序:
三、实现过程
1.配置开发环境
安装 MPLAB X IDE,以及对应的xc8编译器。
https://www.microchip.com/en-us/tools-resources/develop/mplab-x-ide
https://www.microchip.com/en-us/tools-resources/develop/mplab-xc-compilers/xc8
2.MCC配置
创建好新项目后,通过 MCC添加以下模块:
添加 Drivers/Timer/DELAY 用于精确延时
添加 Drivers/ADC 用于获取 ADC 读数生成随机数 seed
· 这里指定 RA2 作为 ADC 检测引脚,设置 Positive Input Channel,和时钟来源。
添加 Drivers/CLB ,并设置:
- Enable CLB: Enabled
- Clock Selection: HFINTOSC
- Clock Divider: Divide clock source by 4
时钟设置:
3. CLB设计
由于 PIC16F13145 只有32个基本逻辑元件阵列,需要精简电路逻辑,并且最多支持 4 个引脚作为 CLB 输入来源,8个引脚作为CLB 输出结果,4个中断输出。所以这里可以设置三路抢答,1路作为reset 按钮。
D触发器带使能和复位功能,非常适合在这里存储抢答状态,当RST = 1时,Q立即被置0,抢答结果清零;当 EN = 1 时,D触发器正常工作,在时钟边沿更新Q值,可以存储新的抢答状态;当 EN = 0 时,D触发器忽略时钟变化,Q保持原值。
输入检测使用下降沿检测,引脚内部设置弱上拉,按下按钮后触发下降沿检测;D触发器和输入之间的AND逻辑门用于判断是否为有效输入,存在锁存结果时,来自 OR 逻辑门的反相结果会使结果为 0;当前没有锁存结果时,D触发器使能开启,可以接收输入,三路抢答检测到输入后锁存结果,并且设置D触发器使能关闭;通过LUT表将结果通过对应的引脚显示在数码管上,同时板载 LED 亮起;复位检测连接系统中断,检测到复位中断后,调用中断函数,中断函数生成随机数用于随机延时,并通过CLBSWIN0 控制复位并显示“J”,延时结束后数码管熄灭,进入下一轮抢答。
启用 Generate ISR ,并设置时钟,Clock Selection: HFINTOSC;Clock Divider: Divide clock source by 4
设置 LUT 表,根据D触发器的输出情况,在不同D触发器输出为1 时,设置 LUT 表的结果;根据触发器的结果可能有 0001,0010,0100三种结果,根据这三种结果设置对应的数字,当reset 值为1时,即1000,LUT 使数码管显示 “J”。
在 Pin Grid View 中分配输入和输出引脚:
由于只显示3个数字,需要6个引脚控制数码管。
- CLBPPSOUT0: RC2 ( 板载 LED,指示抢答成功 )
- CLBPPSOUT1: RA4 ("b" pin 显示引脚)
- CLBPPSOUT2: RB5 ("c" pin 显示引脚)
- CLBPPSOUT3: RA5 ("a" pin 显示引脚)
- CLBPPSOUT4: RC1 ("g" pin 显示引脚)
- CLBPPSOUT5: RB4 ("e" pin 显示引脚)
- CLBPPSOUT6: RB6("d" pin 显示引脚)
输入引脚:
- CLBIN0PPS: RC6 ( 抢答1 )
- CLBIN1PPS: RC7 ( 抢答2 )
- CLBIN2PPS: RB7 ( 抢答3 )
- CLBIN3PPS: RC3 ( 复位触发按键 )
点击 synthesize 后,ide会自动生成对应的代码。
4. 设备连接:
5. 具体代码实现
在main 函数中进行系统初始化,读取 ADC 数值作为随机数 seed;设置 CLB1_IRQ0 中断函数,并启用Global Interrupts。
int main(void)
{
SYSTEM_Initialize();
uint16_t seed0 = ADC_ConversionResultGet();
srand(seed0);
// assign interrupt function
CLB1_CLB1I0_SetInterruptHandler(CLB1I0_Callback);
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
while(1)
{
}
}
ISR 中断触发后会调用CLB1I0_Callback函数,实现延时复位功能。先将 CLBSWIN0 设置为 1,触发复位;生成随机数进行随机延时,延时结束后再将CLBSWIN0 设置为 0,恢复抢答功能。
void CLB1I0_Callback(void)
{
CLBSWINL = 0xff; // reset button
DELAY_milliseconds(50);
uint16_t random = rand(); // Random time generation
random = random / 10;
DELAY_milliseconds(random);
CLBSWINL = 0x0;
}
6 运行
编译好固件并加载;
按下抢答后,数码管显示抢答者编号,按下其它抢答键无效。
按下复位按键后,显示字母“J”,经过随机时间后熄灭,进入下一轮抢答。
四、未来的计划建议
探索CLB 更丰富的可能性。