所有关于电路
项目

嵌入式PID温度控制,第2部分:董事会层面的整合

2016年2月3日,通过罗伯特Keim

这篇文章介绍了固件,允许EFM8单片机与DAC和MAX31855交流。

这篇文章介绍了固件,允许EFM8单片机与DAC和MAX31855交流。

支持信息

在本系列前一篇文章

从图到硬件

上一篇文章介绍了下图的PID控制系统:

从这个图表我们可以建立PID的三个基本组件系统:控制器,执行PID计算;植物,将控制器的计算转化为物理变化;和反馈机制,这意味着身体变化回到模拟或数字信号,可用于控制器的计算。在我们的PID温控器,对应这三个组件,分别EFM8单片机,DAC结合high-current-drive电路(中讨论前一篇文章),MAX31855thermocouple-to-digital转换器。因此,我们的项目的成功取决于可靠通信,可以将这三个功能模块集成到一个统一的PID系统。

SPI(简单,证明接口)

实际上,SPI串行外围接口,但我的选择当然是合适的。我SPI值简单,灵活,低开销的通信协议,这样他们就可以得到每一个单片机和DSP市场上的支持。多么幸运,MAX31855和DAC说SPI。然而,SPI不是固定的,精确定义的协议;它更像是一个普通的串行通信方法。标准的特点如下:

  • 每个设备的总线是主人或奴隶。(可以有多个主,但我建议避免这个。I2C多主机系统是更好的选择。)
  • 电气连接由一个串行时钟信号(SCK),(莫西人,即master-to-slave数据信号。slave-to-master master-out-slave-in),数据信号(味噌,即。master-in-slave-out),并为每一个奴隶一个slave-select信号(NSS)设备。
  • 主启动所有交易通过激活一个或多个NSS线条和驾驶对SCK时钟脉冲。交易继续,只要NSS活跃。
  • 一个事务可以包含数据传输从主人的奴隶(通过莫西人),从奴隶到大师(通过味噌),或两者兼而有之。主可以将数据发送给多个奴隶通过激活所有的NSS线,但为了避免司机争用共享味噌的奴隶必须包含一些方法的信号。

下面的示意图显示了SPI总线上的设备的硬件设计。

完美的时间

这两个图表达的细节SPI总线时间两个奴隶。第一个是MAX31855的数据表,第二个是DAC的数据表。

MAX31855图中,使用CS代替NSS。c代表“芯片选择”,亦表明其活动状态逻辑低;NSS代表“不是奴隶选择”,“不”(而不是一个眉题)表明,它是一个校验信号。

图中DAC,同步代替NSS上划线,尽管在这种情况下,情况有点复杂。兼容的DAC设计各种串行通信协议;这就是为什么计时图看起来不像典型的SPI。但典型的SPI没问题,这就是我们要用的。

如果你仔细观察这两个图,你会注意到一个小但重要的差异:与MAX31855 NSS下降沿后第一次时钟转变由低过渡。DAC,盘中过渡:

这意味着我们需要调整EFM8的SPI配置根据奴隶我们说。下面的图表说明了提供的四个时钟配置选项EFM8 SPI外围;只是比较设备的时间这个图来确定适当的配置细节。

安排数据

SPI是一个可塑的协议,这不仅适用于时间细节,但也格式化的数据。数据传送MAX31855作为一个32位的字,如下:

我们不会担心错误处理对于这个项目,我们不需要知道MAX31855的内部温度,所以我们需要的所有信息都包含在前14位(一点一点31日至18)。然而,EFM8的SPI周边经营单位的字节数,所以我们将读两个字节从MAX31855然后忽略两个最低有效位。

阅读的过程数据MAX31855始于一个名为GatherTempData的函数()和继续通过一个简单的状态机纳入SPI中断服务例程。下面的代码摘录的评论和描述性的标识符应该有助于您理解MAX31855接口的固件的细节。

空白GatherTempData (void){/ /确保我们不会中断一个正在进行的传输而(SPI_State ! =闲置);SPI0CN0_SPIEN = 0;/ /禁用SPI所以我们可以更改时钟配置SPI0CFG & = ~ SPI0CFG_CKPOL__BMASK;/ /设置时钟相位MAX31855接口SPI0CFG & = ~ SPI0CFG_CKPHA__BMASK;/ /设置时钟极性MAX31855接口SPI0CN0_SPIEN = 1;/ /重新启用SPI TC_NSS =低;/ /激活MAX31855奴隶选择/ *我们需要编写一个虚拟字节开始SPI事务。*我们不需要发送任何数据MAX31855;相反,*写SPI0DAT寄存器部队EFM8生成*时钟脉冲导致MAX31855传输数据。* / SPI0DAT = 0 x00;SPI_State = FIRST_TC_BYTE_SENT; }
SI_INTERRUPT (SPI0_ISR SPI0_IRQn) {/ / SPI寄存器SFR所有页面,所以需要需要修改SFRPAGE SPI0CN0_SPIF = 0;/ /清除中断标志开关(SPI_State) {/ / SPI通信与热电偶IC = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =案例FIRST_TC_BYTE_SENT: RawTempData = SPI0DAT;SPI0DAT = 0 x00;/ /写第二个虚拟字节,以便MAX31855将继续发射SPI_State = SECOND_TC_BYTE_SENT;打破;案例SECOND_TC_BYTE_SENT: TC_NSS =高;/ /禁用奴隶选择RawTempData = (RawTempData < < 8) | SPI0DAT;/ *以下指令原始温度*二进制数据转换成格式* Scilab和EFM8容易*转化为一个浮点数。* / TempData [0] = LOWBYTE (RawTempData > > 12);TempData [1] = LOWBYTE (RawTempData > > 4);开关((RawTempData &(第3位| BIT2)) > > 2) {0: TempData [2] = 0; break; case 1: TempData[2] = 25; break; case 2: TempData[2] = 50; break; case 3: TempData[2] = 75; break; } TEMP_DATA_READY = TRUE; SPI_State = IDLE; break; //SPI communications with DAC=========================================== case FIRST_DAC_BYTE_SENT: SPI0DAT = UpdateDAC_SecondByte; SPI_State = SECOND_DAC_BYTE_SENT; break; case SECOND_DAC_BYTE_SENT: DAC_NSS = HIGH; //disable slave select SPI_State = IDLE; break; } }

DAC预计一个16位字,如下所示:

我们将发送两个连续的字节,DAC将这理解为一个16位的词。heater-drive电路连接到DAC通道D,所以前两位二进制11。适当的更新模式对我们来说“写入指定的注册和更新输出,所以第三和第四位二进制01。与MAX31855接口,DAC交易始于UpdateDAC()函数并继续SPI状态机。

空白UpdateDAC (unsigned char ChannelABCorD unsigned char DACcode){/ /确保我们不会中断一个正在进行的传输而(SPI_State ! =闲置);/ *这switch语句集16位DAC的两个最重要的字*根据频道正在更新。它还设置了两个“运行方式”*位二进制01,这对应于“写入指定的寄存器和*更新输出。”* /开关(ChannelABCorD){案例DAC_CH_A: UpdateDAC_FirstByte = 0 x10;打破;案例DAC_CH_B: UpdateDAC_FirstByte = 0×50;打破;案例DAC_CH_C: UpdateDAC_FirstByte = 0 x90;打破;案例DAC_CH_D: UpdateDAC_FirstByte = 0 xd0;打破; } /*The upper four bits of the DAC code are the lower four bits * of the first byte, and the lower four bits of the DAC code are * the upper four bits of the second byte.*/ UpdateDAC_FirstByte = UpdateDAC_FirstByte | (DACcode >> 4); UpdateDAC_SecondByte = DACcode << 4; SPI0CN0_SPIEN = 0; //disable SPI so we can change the clock configuration SPI0CFG |= SPI0CFG_CKPOL__BMASK; //set clock phase for the DAC interface SPI0CFG &= ~SPI0CFG_CKPHA__BMASK; //set clock polarity for the DAC interface SPI0CN0_SPIEN = 1; //re-enable SPI DAC_NSS = LOW; //activate DAC slave select SPI0DAT = UpdateDAC_FirstByte; SPI_State = FIRST_DAC_BYTE_SENT; }

固件

这里是一个链接到下载所有源和项目文件。目前的功能是你所看到的在本文的末尾的视频。

PIDTemperatureControl——Part2.zip

这只是一个测试程序,不同heater-drive大约2.4 V电压从0 V通过不断递增8位值加载到DAC通道D:

int主要(空白){unsigned char Heater_Drive;/ /调用硬件初始化例程enter_DefaultMode_from_RESET ();/ /启用全局中断IE_EA = 1;Heater_Drive = 0;/ /引用PCA ISR信息延迟功能PCA0 = 0 x0000 - PID_INTERVAL;PCA0CN0_CR = PCA_RUN;而(1){PID_WAIT = TRUE;而(PID_WAIT = = TRUE);UpdateDAC (DAC_HEATER Heater_Drive);Heater_Drive + +; } }

之间的延迟DAC updates-referred“PID区间”,因为我们将使用相同的延迟功能与实际PID控制器是通过配置Timer0溢出1 kHz的频率使用Timer0溢出作为可编程计数器的时钟脉冲源数组(PCA),这样,16位PCA计数器/定时器登记每毫秒增加一次。

SI_INTERRUPT (PCA0_ISR PCA0_IRQn) {/ / PCA寄存器SFR所有页面,所以没有需要修改SFRPAGE PCA0CN0_CF = 0;/ /清除中断标志/ *溢出中断时火灾PCA计数器/定时器*从0 xffff到0 x0000溢出,所以我们创建延迟*如下:* / PCA0 = 0 x0000 - PID_INTERVAL;/ / PID_INTERVAL PID_WAIT延迟毫秒= FALSE;}

您可以打开“hwconf”文件访问端口引脚和外围设备的配置细节。同时,请注意,这些源文件包括USB的代码不会被使用,直到后期的项目。

结论

我们已经改变了我们三个PID组件到一个不可阻挡的,无缝集成控温机。在下一篇文章中,我们将实现一个简单的嵌入式PID算法和用示波器测量和变强度导致观察系统的功能。

下一篇文章系列:嵌入式PID温度控制,第3部分:实现和可视化

自己尝试这个项目!的物料清单