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



光导式传感器(图4)的电阻随光强度变化而变化。随着光强度增加,传感器电阻降低,可使传感器流过的电流增大。本例的光传感器采用了photonic detectors, inc.的pdv-p8001,最大电阻(完全黑暗情况下)约200k,最小电阻约3k。


// 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;
}

因为有些显示位的各段分布在一个以上的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("%d\t%d
", local_count, local_sample);
}
为说明接收数据的时序,图7给出了典型办公室环境下打开/关闭电灯时的照度,以及照相机消除红眼闪光灯的照度曲线。为检测这类照相机所使用的双闪光脉冲的特性,这种采样速率和光传感器响应度已足够高。注意,采样值的减小(表示照度增加)几乎与照度变化同时发生,采样值的升高(表示照度降低)显示了光传感器在光强度下降时的调节特性曲线。
