本帖最后由 wangku001wei 于 2012-9-30 21:39 编辑
该程序就是我们通常所说的摇摇棒程序了 首先看原理图 该原理图使用了三个Port组 aPort_YAxia 和三轴加速度的一个引脚向量 dPort_AcclControl和三轴加速度的三个控制引脚相连,用于向加速度传感器写入命令,为高阻态
dPort由8个IO口组成,且由于在POSC的端口设置中如果端口的位宽大于1,则在实际分配引脚时,这些端口必须是同一个Px口上的相邻IO口,因此dPort分为了高低各四位的dPort_LSB和dPort_MSB
为输入引脚
PdPort_LSB 对应P2口的P2[3:0]控制 dPort_MSB 对应P4口的P4[3:0]控制 同样的,反向是因为电路设计为低电平点亮LED,高电平熄灭LED 以上设置可以在引脚分配视图上看出 同时 ADC转换器选择了10位精度,连续转换方式,由软件开启ADC转换
时钟为内部128kHz,在Closks面板中也可以看出 首先简单的来分析下main函数的代码
/******************************************************************************************* * 主函数的功能: * 1: Initializes all variables 初始化所有变量 * 3: Turn off All LEDs on POR 上电复位后关闭所有的LED灯 * 2: Initializes the accelerometer 初始化加速度传感器 * 3: Converts the string to display into a rasterized data array 将需要显示的字符串转化为栅格化的数组 * 4: Start ADC to read acceleration value from Y axis of Accelerometer 开启AD转换读取加速度传感器上Y轴方向的值 * 5: Waits for an acceleration from a wave to be detected. 等待一次摇动开始 * 5: Updates the LEDs with the rasterized message at a periodic rate 用栅格化后的字符以一定的周期速度更新LED /******************************************************************************************/
/*将要显示的字符串*/ const char8 DisplayString[MAX_MESSAGE_NUMBER][STRING_MAX_LEN] = { "PSoC Rocks!", "Customize Message", "By Installing", "PSoC Creator", "From Kit CD", "Open Project",
}; /* 对应的每个字符串挥动显示的次数*/ const uint8 StringCycles[MAX_MESSAGE_NUMBER] = { 30, 7, 7, 7, 7, 7 };
/* 一条信息的像素宽度最大为255 */ // #define MAX_RASTER_LENGTH ((uint8) 255) uint8 DisplayRasterTable[MAX_RASTER_LENGTH];
void main() { // 光栅像素数组的索引 uint8 RasterCount; /* The current raster column data to output to the LEDs */ // 当前显示的第几条字符串 uint8 MessageNumber; // 当前字符串挥动显示的次数 uint8 Cycles; // 当前字符串转换为光栅像素数据后的数组长度 uint8 RasterLength;
/*初始化硬件*/ CYGlobalIntEnable; /* 使能全局中断 */ LED_Control_Reg_Write(0); /* 熄灭LED灯 */ /*控制加速度传感器 ENABLE=1, MODE=1, ST/MODE=LOW */ // #define ACCL_SET_CONTROL ((uint8) 0x06) dPort_AcclControl_Write(ACCL_SET_CONTROL);
// 开始AD转换 AcclADC_Start();
/* 当挥动时循环显示字符串 */ while(1) { for(MessageNumber = 0; MessageNumber < MAX_MESSAGE_NUMBER; MessageNumber++) { /* 将当前需要显示的一行字符串转换为光栅数据数组,并返回该数组的长度/ RasterLength = LED_StringProcess(DisplayString[MessageNumber]);
/* 将当前需要显示的一行字符串循环显示多次 */ for(Cycles = 0; Cycles < StringCycles[MessageNumber]; Cycles++) { /*等待挥动开始 */ do { AcclADC_StartConvert(); AcclADC_IsEndConversion(AcclADC_WAIT_FOR_RESULT); }while(AcclADC_GetResult16() > ACCEL_TRIGGER);
/* 在LED 开始显示和开始挥动之间进行延时*/ LED_Delay(INITIAL_DELAY);
/* 将每列光栅数据输送到8位LED上,同时每列光栅数据间进行延时 */ for(RasterCount = 0; RasterCount < RasterLength; RasterCount++) { LED_Delay(RASTER_DELAY); LED_Control_Reg_Write(DisplayRasterTable[RasterCount]); }
/* 等待这次挥动结束 */ do { AcclADC_StartConvert(); AcclADC_IsEndConversion(AcclADC_WAIT_FOR_RESULT); }while(AcclADC_GetResult16() < (255 - ACCEL_TRIGGER)); } } } }
关于字符串(尤其是字符)向光栅数组的转换,可参考单片机点阵工具之类的软件 比如说 采用PCtoLCD转换中文 王
采用自下而上的方式
结果是 00H 02H 2AH 3EH 2AH 2AH 42H 00H;"王",0
对于PSoC上的转换过程分析 首先程序用一个二维数组font8x5将不同英文字符对应的光栅像素数据保存 每个字符由水平5个像素垂直8个像素表示 并且每垂直的8个像素值用一个字节保存 以字符’A’为例
{0x3F,0x48,0x88,0x48,0x3F}, // ASCII - 65 A 可以看出 采用从上到下 从左到右的顺序
然后 程序调用LED_StringProcess函数将一行字符串中的每个字符转换为光栅像素数据保存在DisplayRasterTable数组中,并返回当前光栅像素数组的长度
uint8 LED_StringProcess(char8 CurrentDisplayString[STRING_MAX_LEN]) { uint8 CharCount = 0; /* 字符转中需要转换的单个字符的索引 */ uint8 CurrentChar = 0; /* 当前正在转换的字符 */ uint8 CharRasterCount = 0; /* 当前转换字符的光栅数据的索引*/ uint8 RasterCount = 0; /* 当前光栅数组中的索引 */
CharCount = 0; RasterCount = 0; while(CurrentDisplayString[CharCount] != 0) /* 循环处理字符串中的数据直到字符串结束 */ { /* 对于字符串中的每个字符,以此添加其对应的光栅数据到光栅数据数组中 */ CurrentChar = CurrentDisplayString[CharCount]; for(CharRasterCount = 0; CharRasterCount < CHAR_WIDTH; CharRasterCount++) { /* 减去0x20(由于光栅二维数组从ADCII码的0x20字符(空格space)开始的) */ DisplayRasterTable[RasterCount] = font8x5[CurrentChar-0x20][CharRasterCount]; RasterCount++; } DisplayRasterTable[RasterCount] = 0x00; /* 在两个字符之前添加个空格 */ RasterCount++; CharCount++; } return RasterCount; /*返回光栅数组的实际长度 */ }
代码分析简单到此 希望对大家有帮助 |