用Rowley CrossWorks和MAXQ3120评估板创建照度计应用系统
maxq3120评估板包含了演示maxq3120主要功能所需要的元件,用户使用该评估板,可以在硬件设计的同时,立即进行软件开发。该评估板具有以下特征:
本文引用地址:https://www.eepw.com.cn/article/21288.htm带8mhz晶振的80引脚mqfp封装maxq3120微控制器
串口-jtag接口板,可以采用pc主机编程和调试
3.3v线性调节器,直接通过jtag接口为maxq3120供电
maxq3120直接驱动的静态3.5位lcd显示器
复位和外部中断按钮
对应maxq3120串口1的rs-232接口和连接器
包含模拟vdd和4个模数转换器(adc)输入引脚连接点的原型设计区
本系统配合使用串口-jtag接口电路板(图1),可以完全实现maxq3120的在系统引导装入和调试功能。

图1. maxq3120评估板和串口-jtag电路板共同构成完整的应用开发系统。 在rowley crossworks中创建工程
一旦激活产品(见rowley网站的"support:evaluating crossworks"),运行crossworks。选择菜单中的file new new project,创建一个新工程。在new project options对话框中(图2),选择"c executable",输入工程的名称和存储位置。在随后的project setup对话框(见图3),确认"target processor"选项为maxq3120。其它选项可保留为缺省值。点击finish创建新工程。

图2. 创建新工程的第一步:选择可执行程序类型。

图3. 该工程的目标处理器为maxq3120。 应用概要
本maxq3120演示示例着重展示了处理器的三项关键特性:adc、lcd控制器和uart接口。使用这些外设,我们可以创建完成以下功能的应用系统,该应用精确测量电压,在lcd上显示这些电压,并通过usart串行接口发送数据。可下载本示例的完整代码。
maxq3120 adc接口的满量程测量范围可配置为-1v到+1v之间,并在两个通道中任何一个通道的两输入引脚间进行差分测量。要进行光照强度测量,我们需要一种简单方法来产生处于该量程范围内的随周围光线变化的电压。
光导式传感器(图4)的电阻随光强度变化而变化。随着光强度增加,传感器电阻降低,可使传感器流过的电流增大。本例的光传感器采用了photonic detectors, inc.的pdv-p8001,最大电阻(完全黑暗情况下)约200k,最小电阻约3k。

图4. 光导式传感器的阻抗随光照强度增加而减小。 阻性传感器的连接如图5所示,该连接方式使我们可以将传感器与maxq3120 adc的一个输入通道连接,而不用考虑传感器的最小和最大电阻。即使在完全短路(结果电压为0v)或者开路(结果电压为0.825v)的最坏情况下,输入电压也不会超出adc通道的允许范围。

图5. 使用本adc输入电路可测量任何类型的电阻传感器 测量光照强度
我们必须首先测量maxq3120 adc通道的输入电压。当新的电压采样就绪后,adc 产生一个中断,因此我们只需初始化adc并使能中断。
// initialize the adc
adcn = 0x0030; // flush samples
adcn = 0x0300; // power down
adcn = 0x0200; // power up
imr = 0x08; // enable interrupts from module 3
ic = 0x01; // enable interrupts globally
在crossworks中,任何函数都能通过在函数定义中增加_interrupt关键字,而被指定为中断服务函数。因为maxq3120的所有中断均指向iv寄存器内包含的地址,所以我们只需要定义一个中断服务函数。本应用程序仅使用了一个中断,如果我们想增加其他中断,可以在中断服务函数内检查其他寄存器,以确定哪个中断触发了中断服务函数。
void adc_interrupt(void) __interrupt
{
current_sample = (int)adc0;
sample_count++;
}
void main(void)
{
setiv(adc_interrupt);
...
中断服务函数adc_interrupt求取adc通道0最后16个采样结果的移动平均值。这可滤除输入的高频噪声,并获得大约2.4khz的输出采样率。由于显示和传输采样的频率相当低,所以本应用系统的性能不会受到影响。
显示采样电压
为简单起见,我们直接显示从adc通道0读出的原始电压,来表示所测量的光照强度。该电压在0到1v之间,能以0.001v的精度在所包含的lcd显示器上显示。
maxq3120评估板上的lcd采用3.5位静态lcd,带有正/负和小数点指示,布局如图6所示。与lcd接口的第一步是初始化maxq3120
lcd控制器。
void lcd_init(void)
{
lcra = 0x02e0; // 0000 0010 1110 0000, static, 32khz, radj=0
lcfg = 0xf3; // use all pins, enable display
lcd0 = 0xff; // initialize all segments to on
lcd1 = 0xff;
lcd2 = 0xff;
lcd3 = 0x0f;
}

图6. maxq3120评估板为应用提供3.5位静态lcd。 lcd初始化完成后,我们即可增加代码,设置显示器的适当段来显示某特定的数值。lcd的各个段与各寄存器位一一对应(表1),因此在显示器上显示字符只需简单地向各寄存器写入合适的数值。lcd控制器处理余下的问题。

unsigned char lcd0_mask[] =
{
0xff, // digit 0 (rightmost)
0x7f, // digit 1 (center)
0x80 // digit 2 (leftmost)
};
....
unsigned char lcd0_table[] =
{
// digit 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// digit 1
0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80,
// digit 2
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67
};
....
void lcd_display(int value, int digit)
{
int index;
if ((digit == 0) || (digit == 1) || (digit == 2)) {
index = digit * 10 + value;
lcd0 &= lcd0_mask[digit];
lcd1 &= lcd1_mask[digit];
lcd2 &= lcd2_mask[digit];
lcd0 |= lcd0_table[index];
lcd1 |= lcd1_table[index];
lcd2 |= lcd2_table[index];
}
}
这些子程序准备就绪后,所有剩下的问题就是将采样平均值转换成十进位形式,并在lcd上显示。因为采样速率比lcd显示采样结果或人眼睛能看到的结果快得多,本应用程序在各次lcd刷新之间加入一个延时循环。在中断程序中获得各采样结果并连续求得平均值,但这些平均采样值只是周期性地在lcd上显示。
while (1)
{
ic = 0; // clear interrupts to make sure we copy correctly
ltemp = current_sample; // from our global variable to our local
copy
local_count = interrupts;
ic = 1; // enable interrupts ends the critical section
ltemp = ltemp * 100;
// divide by 32k
ltemp = ltemp >> 15;
local_sample = (int) ltemp;
sign = 0;
if (local_sample < 0) {
sign = 1;
local_sample = local_sample * -1;
}
lcd_display(local_sample % 10, 0);
local_sample = local_sample / 10;
lcd_display(local_sample % 10, 1);
local_sample = local_sample / 10;
lcd_display(local_sample % 10, 2);
local_sample = local_sample / 10;
if (local_sample != 0) {
// set leading 1
lcd_set1000s();
}
if (sign == 1) {
lcd_setnegative();
} else {
lcd_setpositive();
}
for (counter = 0; counter < 1000; counter++) {
// just a simple delay loop
}
}
每当电平上升到0.5v以上(local_sample > 50)时,我们就点亮一只led (由端口引脚p0.6驱动),作为额外指示。环境光线强度一旦低于某一特定水平(如关掉房间电灯时),led的发光指示可产生一种“夜光”效果。
if (local_sample > 50) {
po0 = 0x8f;
} else {
po0 = 0xff;
}
向pc返回结果
在可视化显示的同时,我们可扩展本应用程序的功能,将采样值送到pc主机,用于后续处理和分析。最简单的方法是向串口1写ascii码数据,经电平转换并送入db9
rs-232连接器。然后, 只需简单地将串口与pc连接,使用一个标准终端仿真程序获取数据。
crossworks提供标准的c printf()函数,作为其基本库的一部分,这样,将数据格式转换成ascii码十进制形式的大部分工作已经完成。所有剩下的工作是初始化和控制传送数据的串口。通过定义_putchar函数在串口输出一个字符,实现与printf()的接口。这样,printf()将在必要时自动调用此函数。
int initserial(void)
{
scon1 = (1<<6)|(1<<4); // set to mode 1 (10-bit asynchronous)
& enable
smd1 = 2; // baud rate = 16 x baud clock
pr1 = 0x095d; // p = 2^21 * 9600 / 8mhz crystal
}
int __putchar(int x)
{
sbuf1 = x;
while (!(scon1 & 2));
scon1 &= ~2;
}
为确定输出采样之间的时间间隔,本应用程序在通过串口发送每个采样时,同时发送原始的adc中断次数。在9600波特率下,通过串口输出10个字符约需100ms。
只有在用户请求时数据才写入串口,通过按下maxq3120评估板上pb1-pb4中的任何一个按钮实现该操作。
if ((pi0 & 0x27) != 0x27) {
printf("%dt%d
", local_count, local_sample);
}
为说明接收数据的时序,图7给出了典型办公室环境下打开/关闭电灯时的照度,以及照相机消除红眼闪光灯的照度曲线。为检测这类照相机所使用的双闪光脉冲的特性,这种采样速率和光传感器响应度已足够高。注意,采样值的减小(表示照度增加)几乎与照度变化同时发生,采样值的升高(表示照度降低)显示了光传感器在光强度下降时的调节特性曲线。

图7. 测量照相机消除红眼闪光灯时得到这些光强采样结果。 结语
maxq3120集成了通用双通道adc,其处理能力足以应付复杂的信号分析任务。除此之外,maxq3120还具备充足的能力进行显示控制、与主机通讯以及完成数据采集系统需要的其他任务。再加上rowley associates的crossworks所提供的完备工具和开发环境鼎力相助,任何不具备maxq处理器架构专门知识的人,都能很快使用标准ansi c开发和调试数据采集及处理应用程序。
评论