Freescale芯片智能小车程序分析
#include <hidef.h> #include <MC9S12XS128.h> #pragma LINK_INFO DERIVATIVE "mc9s12xs128" #define PITTIME 5000 //50MS定时中断 #define speed_set1 3200 #define speed_set2 2000 #define NB 150 //直道最小速度 #define NS 250 //直道中小速度 #define Z 350 //中速 #define PS 500 //中高速 #define PB 600 //高速 #define NB1 275 //弯道最小速度 #define Z1 325 //中速 #define PS1 350 //中高速 #define PB1 375 //高速 int speed_data[5][7] = //直道速度表 { { NB, NB, NS, Z, PS, Z, NS }, { NB, NS, Z, PS, PB, PB, Z }, { NS, Z, PS, PB, PS, Z, NS }, { Z, PS, PB, PS, Z, NS, NB }, { NS, Z, NS, Z, NS, NB, NB } }; int speed_data0[5][7] = //弯道速度表 { { NB1, NB1, NS1, Z1, PS1, Z1, NS1 }, { NB1, NS1, Z1, PS1, PB1, PB1, Z1 }, { NS1, Z1, PS1, PB1, PS1, Z1, NS1 }, { Z1, PS1, PB1, PS1, Z1, NS1, NB1 }, { NS1, Z1, NS1, Z1, NS1, NB1, NB1 } }; int ad_data[10][11]; int ad_data1[11]; int pd_data[11]; int ad_min[11] = { 40, 20, 20, 30, 50, 50, 50, 50, 60, 50, 50 }; //新 int ad_mid[11]; int state; int start_flag = 1; //启停标志 int straight_flag = 1; //直弯标志 int count = 0; int B_cnt; int B_cnt_last; int count1 = 0; //赛道特殊状况检测次数 int count3 = 0; //直弯检测累计 int count4 = 0; int state_first = 0; //赛道状态传递 int state_last = 0; int state_now; int state_e = 0; int state_e_last; int u; int v = 200; int steer_e; //舵机增量 float Kp = 2; //舵机K float Kp_data[11] = { 0.6, 0.65, 0.82, 0.83, 0.84, 0.90, 0.95, 1.1, 1.35, 1.47, 1.59 }; float Kp_data2[11] = { 0 }; float Kd = 0.5; //舵机D float Kp_s = 0.008; //速度K float Ki_s = 0; //速度I float Kd_s = 0; //速递D int steer = 2600; int speed; //光电编码器测速值 int speed_e_first = 0; int speed_e_last = 0; int speed_e; int speed_set; //速度设定值 int motor_e; int motor_pwm; //初始化// void PLL_Init(void) //PLLClK=2*OSCCLK*(SYNR+1/REFDV+1) { //锁相环=2*16=32MHz REFDV = 1; //总线时钟=32/2=16MHz SYNR = 1; while (!(CRGFLG & 0x08)); CLKSEL = 0X08; //时钟选择,等待模式下锁相环停止工作 } void PWM_Init(void) { PWME = 0x00; PWMCTL = 0x70; //级联方式 PWMPOL = 0xff; PWMCAE = 0xff; //对齐方式左对齐 PWMCLK = 0x30; //PWM时钟选择,23通道CLOCKSB PWMPRCLK = 0x11; //PWM预分频,时钟源A=时钟源B=8MHz PWMSCLA = 5; PWMSCLB = 5; PWMPER01 = 1000; PWMDTY01 = 0; PWMPER45 = 1000; PWMDTY45 = 200; PWMPER23 = 16000; PWMDTY23 = 0; PWME = 0x3f; } void AD_Init(void) { ATD0CTL0 = 0x0A; ATD0CTL1 = 0x00; //7:1-外部触发,65:00-8位精度,4:放电,3210:ch ATD0CTL2 = 0x40; //禁止外部触发, 中断禁止 ATD0CTL3 = 0xD8; //右对齐无符号,每次转换11个序列, No FIFO, Freeze模式下继续转 ATD0CTL4 = 0x01; //765:采样时间为4个AD时钟周期,ATDClock=[BusClock*0.5]/[PRS+1] ATD0CTL5 = 0x30; //6:0特殊通道禁止,5:1连续转换 ,4:1多通道轮流采样 ATD0DIEN = 0x00; //禁止数字输入 } void PIT_Init(void) { PITCFLMT_PITE = 0; //PIT关 PITCE_PCE0 = 1; //定时器通道0使能 PITMTLD0 = 160 - 1; //8位定时器初值设定。160分频,在16MHzBusClock下,为0.1MHz。即 10us. PITLD0 = PITTIME - 1; //16位定时器初值设定。PITTIME*0.01MS 50ms定时 PITINTE_PINTE0 = 1; //定时器中断通道0中断使能 PITCFLMT_PITE = 1; //PIT使能 } void PACA_Init(void) //初始化脉冲累加器A { TCTL3 = 0X40; //下降沿捕捉脉冲 PACTL = 0x40; //脉冲累加使能 PACNT = 0X0000; } //功能函数// void delay_ms(int ms) //延时函数 { int i, j; for (i = 0; i < ms; i++) for (j = 0; j < 2770; j++); //16MHz--2ms } int abs(int num) //绝对值 { if (num<0) return -num; else return num; } void Reverse(int* arr, int b, int e) //数组元素对换 { for (; b < e; b++, e--) { int temp = arr[e]; arr[e] = arr[b]; arr[b] = temp; } } void RightShift(int* arr, int N, int K) //数组循环移位 { K %= N; Reverse(arr, 0, N - K - 1); Reverse(arr, N - K, N - 1); Reverse(arr, 0, N - 1); } //单片机处理/ void ATD_data(void) //AD采集 { int i; for (i = 0; i<10; i++) { while (!ATD0STAT0_SCF); ad_data[i][0] = ATD0DR0L; ad_data[i][1] = ATD0DR1L; ad_data[i][2] = ATD0DR2L; ad_data[i][3] = ATD0DR3L; ad_data[i][4] = ATD0DR4L; ad_data[i][5] = ATD0DR5L; ad_data[i][6] = ATD0DR6L; ad_data[i][7] = ATD0DR7L; ad_data[i][8] = ATD0DR8L; ad_data[i][9] = ATD0DR9L; ad_data[i][10] = ATD0DR10L; ATD0CTL5 = 0x30; } } void PD_data(void) //AD数据处理 { int i, j, k, temp; for (i = 0; i<10; i++) //每个传感器采样10次的数据进行排序 { for (j = 0; j<11; j++) for (k = j + 1; k<10; k++) { if (ad_data[j][i]>ad_data[k][i]) { temp = ad_data[j][i]; ad_data[j][i] = ad_data[k][i]; ad_data[k][i] = temp; } } } for (j = 0; j<11; j++) //对中间的两个值求平均作为本次采集的结果 ad_data1[j] = (ad_data[4][j] + ad_data[5][j]) / 2; } void STATE_data(void) //位置判断 { int i; B_cnt_last = B_cnt; //B_cnt为当前检测到黑线传感器的个数 B_cnt = 0; for (i = 0; i<11; i++) //对采集的数据进行二值化处理 { ad_mid[i] = ad_min[i] + 60; (ad_data1[i]<ad_mid[i]) ? (pd_data[i] = 1) : (pd_data[i] = 0); } for (i = 0; i<11; i++) //位置计算,判断采集黑线传感器的个数 { if (pd_data[i] == 1) B_cnt++; } if (B_cnt == 1) for (i = 0; i<11; i++) //判断黑线的位置 { if (pd_data[i] == 1) state = 2 * i - 10; } if (B_cnt == 2) for (i = 0; i<10; i++) { if (pd_data[i] == 1 && pd_data[i + 1] == 1) state = 2 * i + 1 - 10; } if (B_cnt>5 && B_cnt_last<6) //特殊状况,十字,起跑线 count1++; } void START_judge(void) //起跑线识别 { int i, knum, SATurn; int kA[4] = { 0 }; if (count1>2) for (i = 0, knum = 0, SATurn = 0; i<10; i++) if (pd_data[i] ^ pd_data[i + 1]) { SATurn++; kA[knum] = i; knum++; } if (SATurn == 4) if ((kA[1] - kA[0]) <= 2 && (kA[1] - kA[0]) >= 1 && //起跑线左白区域 (kA[2] - kA[1]) <= 2 && (kA[2] - kA[1]) >= 1 && //起跑线中黑区域 (kA[3] - kA[2]) <= 2 && (kA[3] - kA[2]) >= 1 && //起跑线右白区域 (B_cnt <= 9 && B_cnt >= 7)) //状态1传感器总数 start_flag = 0; } void STATE_judge(void) //滤波&&直弯判断 { state_last = state_now; state_now = state; if (abs(state_now - state_last)>2) { state_now = state_last; } if (count3<40) count3++; if (abs(state_now)<5) count4++; if (count3 == 40 && count4>35) { straight_flag = 1; count3 = 0; count4 = 0; } if (count3 == 40 && count4<30) { straight_flag = 0; count3 = 0; count4 = 0; } Kp = Kp_data[abs(state_now)]; } void STATE_e(void) //误差变化计算 { if (count == 0) { state_first = state_now; } count++; if (count>5) { state_e_last = state_e; state_e = state_now - state_first; count = 0; } } void STEER_pd(void) //舵机PD控制 { /* if(abs(state_now)<4) //速度对转角的影响,速度大时,直道K值取小 Kp-=speed/speed_set1; if(abs(state_now)>4) //弯道K值随速度增大 Kp+=speed/speed_set2; */ //Kp=Kp_data[abs(state_now)]; steer = (int)(2550 + Kp*state_now * 70 + Kd*(state_e - state_e_last) * 70); // steer+=(int)(Kp*(state_now-state_last)*80+Kd*(state_e-state_e_last)*80); if (steer > 3400) { steer = 3400; } if (steer < 1700) { steer = 1700; } PWMDTY23 = steer; } void SPEED_set(void) { int i, j; if (state_e>4) i = 4; else if (state_e<-4) i = 0; else { i = (state_e + 4) / 2; j = (state_now + 10) / 3; } if (straight_flag == 1) speed_set = speed_data[i][j]; if (straight_flag == 0) speed_set = speed_data0[i][j]; // speed_e_first=speed_e_last; speed_e_last = speed_e; speed_e = speed_set - speed; } void SPEED_pd(void) { if (start_flag == 0) { delay_ms(50); PWMDTY01 = 200; } else { if (speed_set - speed>300) { motor_pwm = 700; } else if (speed_set - speed<-300) { motor_pwm = 0; } else { motor_e = (int)(Kp_s*speed_e + Kd_s*(speed_e - speed_e_last)); //motor_e = (int)(Kp_s*(speed_e-speed_e_last)+Ki_s*speed_e+ // Kd_s*(speed_e-2*speed_e_last+speed_e_first)); motor_pwm = motor_e + v; v = motor_pwm; } PWMDTY01 = motor_pwm; } } /* 定时中断 */ \#pragma CODE_SEG __NEAR_SEG NON_BANKED void interrupt 66 PIT0(void) { PITTF_PTF0 = 1; //清中断标志位 speed = PACNT; PACNT = 0x0000; } /********************************/ /* 主函数 */ /********************************/ void main(void) { PLL_Init(); PWM_Init(); AD_Init(); PIT_Init(); PACA_Init(); EnableInterrupts; for (;;) { ATD_data(); PD_data(); STATE_data(); START_judge(); STATE_judge(); STATE_e(); SPEED_set(); STEER_pd(); SPEED_pd(); } } 这份源代码的不足和错误还是比较多, for(i=0;i<10;i++) //每个传感器采样10次的数据进行排序
July 19, 2010
离散事件模拟
/* by SonicRang */ #include <iostream> #include <stdlib.h> #include <time.h> #include <windows.h> using namespace std; #define WINDOW 5 //定义服务窗口个数 /* 定义各窗口服务队列 */ typedef struct qnode { int arrivetime; //到达时刻 int duration; //处理时长 struct qnode *next; }Qnode, *Queptr; typedef struct { Qnode *front, *rear; int length; }LinkQueue; /* 定义结束 */ /* 定义一天内所有事件链表 */ typedef struct enode { int occurTime, NType; //事件发生时刻,事件类型(0:未发生 非0:已完成) struct enode *next; }Enode, *Eptr; typedef struct { Enode *front, *rear; int eventNum; //事件数 }EventList; /* 定义结束 */ /* 定义全局变量 */ EventList *eventlist; //事件链表 LinkQueue q[WINDOW + 1]; //窗口队列 Eptr pe, ev; //事件节点 int seed = 300; int closetime; //银行工作时长 int totaltime; //总时间 int customerNum; //客流量 /* 定义结束 */ /* 插入客户事件到事件链表 */ void InsertEvent(EventList *eventlist, int Time, int Type) { Eptr p, q, location; p = new Enode; p->occurTime = Time; p->NType = Type; eventlist->eventNum++; q = eventlist->front; location = NULL; while (q && (Time > q->occurTime)) //找到插入位置 { location = q; q = q->next; } if (location == NULL) //找到了空队列插入到队头 { p->next = eventlist->front; eventlist->front = p; } else //找到了非空队列插入到队尾 { p->next = q; location->next = p; } if (eventlist->eventNum == 1) //初始化队尾 { eventlist->rear = p; } } /* 插入完成 */ /* 删除事件链表中的事件 */ void DeletEvent(EventList *ev, Eptr &data) { Eptr p; p = ev->front; ev->front = p->next; if (--ev->eventNum<1) { ev->rear = ev->front; } data = p; } /* 删除完成 */ /* 当前客户插入窗口队列 */ void EnQueue(LinkQueue *q, int t1, int t2) { Queptr p; p = new Qnode; p->arrivetime = t1; p->duration = t2; q->length++; if (q->length == 1) //只有一个元素的队列处理 { p->next = NULL; q->front = q->rear = p; } else { p->next = q->rear->next; } q->rear->next = p; q->rear = p; //重连接队列 } /* c插入完成 */ /* 当前客户出窗口队列进行处理 */ void DeQueue(LinkQueue *q, Queptr f) { Queptr p; if (q->length>0) { f->arrivetime = q->front->arrivetime; f->duration = q->front->duration; p = q->front; q->front = q->front->next; q->length--; if (q->length == 0) q->rear = NULL; delete (p); } } /* 处理结束 */ /* 找最短队列 */ int Minlength() { int min, j, i; min = q[1].length; j = 1; for (i = 2; i <= WINDOW; i++) if (q[i].length < min) { min = q[i].length; j = i; } return j; } /* 查询完成 */ /* 初始化银行 */ void Open() { int i; eventlist = new EventList; pe = new Enode; pe->occurTime = 0; //初始化发生事件事件 pe->NType = 0; pe->next = NULL; eventlist->front = pe; //插入第一个客户到事件表 eventlist->rear = pe; eventlist->eventNum = 1; for (i = 1; i < WINDOW + 1; i++) //初始化服务窗口队列为空 { q[i].front = q[i].rear = NULL; q[i].length = 0; } } /* 初始化结束 */ /* 客户到达 */ void CustomerArrived() { int durtime, intertime, min; customerNum++; //客流量增加 srand((unsigned)time(NULL)); Sleep(1000); durtime = 5 + rand() % 31; //产生随机数(当前客户所需的服务时间和下一个用户到达的时间间隔) intertime = 5 + rand() % 11; if ((ev->occurTime + intertime) < closetime) InsertEvent(eventlist, ev->occurTime + intertime, 0); //下一个客户到事件加入事件表 min = Minlength(); //找最短队列 EnQueue(&q[min], ev->occurTime, durtime); //客户加入窗口 cout << "客户于<" << ev->occurTime << ">时刻进入" << min << "号窗口," << "处理了" << durtime << "分钟" << endl; if (q[min].length == 1) InsertEvent(eventlist, ev->occurTime + durtime, min); //唯一客户加入离开事件 } /* 函数结束 */ /* 客户离开 */ void CustomerLeave() { int i; i = ev->NType; //第i号窗的客户离开 Queptr data; data = new Qnode; DeQueue(&q[i], data); //删除i号窗口的排头客户 cout << i << "号窗口客户离开" << endl; totaltime += ev->occurTime - data->arrivetime; //总时间累积 if (q[i].length != 0) //插入离开事件 InsertEvent(eventlist, ev->occurTime + q[i].front->duration, i); } /* 函数结束 */ /* 主函数 */ void main() { cout << "**************银行模拟系统**************" << endl; cout << "请输入银行营业时长(分钟):" << endl; cin >> closetime; Open(); //初始化银行 while (eventlist->eventNum > 0) //事件非空开始执行 { DeletEvent(eventlist, ev); //取事件表中的第一个事件节点 if (ev->NType == 0) //处理客户到达事件 CustomerArrived(); else CustomerLeave(); //处理离开事件 } cout << "今日客流量:" << customerNum << endl; cout << "平均处理时间:" << totaltime / customerNum << "分钟" << endl; system("pause"); }
July 10, 2010
线索树
最近懒了,贴篇源码补补空闲…… using namespace std; typedef struct bithrnode { char data; struct bithrnode *lchild; struct bithrnode *rchild; int ltag, rtag; }BiThrNode, *BiThrTree; BiThrTree pre; void InitBTree(BiThrTree &BT); void CreatBTree(BiThrTree &BT); void AddThread(BiThrTree p); void ThreadTree(BiThrTree BT, BiThrTree &head); BiThrTree InorderNext(BiThrTree p); void ThInorder(BiThrTree head); void InitBTree(BiThrTree &BT) { BT = NULL; } void CreatBTree(BiThrTree &BT) { char ch; ch = getchar(); if (ch == ' ') BT = NULL; else { BT = new BiThrNode; BT->data = ch; BT->ltag = 0; BT->rchild = 0; CreatBTree(BT->lchild); CreatBTree(BT->rchild); } } void ThreadTree(BiThrTree BT, BiThrTree &head) { head = new BiThrNode; head->data = NULL; head->ltag = 0; head->rtag = 0; head->rchild = head; if (BT == NULL) head->lchild = head; else { pre = head; head->lchild = BT; AddThread(BT); pre->rchild = head; pre->rtag = 1; head->rchild = pre; head->rtag = 1; } } void AddThread(BiThrTree p) { if (p != NULL) { AddThread(p->lchild); if (p->lchild == NULL) { p->ltag = 1; p->lchild = pre; } if (pre->rchild == NULL) { pre->rtag = 1; pre->rchild = p; } pre = p; AddThread(p->rchild); } } BiThrTree InorderNext(BiThrTree p) { if (p->rtag == 1) return p->rchild; else { p = p->rchild; while (p->ltag == 0) p = p->lchild; return p; } } void ThInorder(BiThrTree head) { BiThrTree HT; HT = head->lchild; while (HT != head) if (HT != NULL) { while (HT->ltag == 0) HT = HT->lchild; while (HT != head) { cout << HT->data << ' '; HT = InorderNext(HT); } } } void main() { BiThrTree T, head; InitBTree(T); cout << "InitTree completed!" << endl; cout << "Create Tree:" << endl; CreatBTree(T); ThreadTree(T, head); cout << "The ThreadTree is Inordered:" << endl; ThInorder(head); system("pause"); }
July 1, 2010
c#制作视频音频歌词相关技术代码记录
开发类似千千静听或者KMplayer等音频视频播放器播放字幕或者歌词的技术 从两方面着手,一是时间轴,二是帧(对于视频)。 方法一的实现比较简单,只需要内置一个定时器,在媒体播放时开始计时,然后读指定的脚本即可。
July 1, 2010
C#调用IE浏览器设置
using System.Diagnostics; ProcessStartInfo Info=new ProcessStartInfo(); Info.FileName = "inetcpl.cpl "; Process.Start(Info);
May 29, 2010
数据结构cpp二叉树
using namespace std; typedef struct btreenode { char data; struct btreenode *lchild; struct btreenode *rchild; }BTreeNode, *BTree; typedef struct { BTree link; int flag; }Stack; void InitBTree(BTree &BT) { BT = NULL; } void CreatBTree(BTree &BT) { char ch; ch = getchar(); if (ch == ' ') BT = NULL; else { BT = new BTreeNode; BT->data = ch; CreatBTree(BT->lchild); CreatBTree(BT->rchild); } } void PreOrder(BTree BT) { if (BT == NULL) { cout << "NULL"; return; } else { cout << BT->data; if (BT->lchild != NULL) PreOrder(BT->lchild); if (BT->rchild != NULL) PreOrder(BT->rchild); } } void InOrder(BTree BT) { if (BT == NULL) { cout << "NULL"; return; } if (BT->lchild != NULL) InOrder(BT->lchild); cout << BT->data; if (BT->rchild != NULL) InOrder(BT->rchild); } void PostOrder(BTree BT) { if (BT == NULL) { cout << "NULL"; return; } if (BT->lchild != NULL) PostOrder(BT->lchild); if (BT->rchild != NULL) PostOrder(BT->rchild); cout << BT->data; } void LevelOrder(BTree BT) { BTree Queue[30]; int front, rear; if (BT == NULL) return; front = -1; rear = 0; Queue[rear] = BT; while (front != rear) { front++; cout << Queue[front]->data; if (Queue[front]->lchild != NULL) { rear++; Queue[rear] = Queue[front]->lchild; } if (Queue[front]->rchild != NULL) { rear++; Queue[rear] = Queue[front]->rchild; } } } void PreOrder_2(BTree BT) { BTree stack[30], p; int top; if (BT == NULL) return; top = -1; p = BT; while (!(p == NULL && top == -1)) { while (p != NULL) { cout << p->data; if (top < 30) { stack[top + 1] = p; top++; } else { cout << "Stack is full!" << endl; return; } p = p->lchild; } if (top < 0) return; else { top--; p = stack[top + 1]; p = p->rchild; } } } void PostOrder_2(BTree BT) { Stack s[30]; BTree p; int top, sign; if (BT == NULL) return; top = -1; p = BT; while (!(p == NULL && top == -1)) { if (p != NULL) { s[++top].link = p; s[top].flag = 1; p = p->lchild; } else { p = s[top].link; sign = s[top].flag; top--; if (sign == 1) { s[++top].link = p; s[top].flag = 2; p = p->rchild; } else { cout << p->data; p = NULL; } } } } void main() { BTree T; InitBTree(T); cout << "InitTree completed!" << endl; cout << "Create Tree:" << endl; CreatBTree(T); cout << "/nPreOrder:" << endl; PreOrder(T); cout << "/nInOrder:" << endl; InOrder(T); cout << "/nPosetOrder:" << endl; PostOrder(T); cout << "/nLevelOrder:" << endl; LevelOrder(T); cout << "/nPreOrder_2:" << endl; PreOrder_2(T); cout << "/nPostOrder_2:" << endl; PostOrder_2(T); system("pause"); }
May 21, 2010
重装Windows后修复引导ubuntu
重装了windows后ubuntu就不能自动引导了,网上有很多方法,这里只说两种简单的 win xp: 复制wubildr.mbr,wubildr到C盘(这两个文件在安装Ubuntu磁盘下的winboot文件夹中)
May 15, 2010
Win7安装vs2010
安装VS2010到内牛满面 开始在win7 64位旗舰版下遇到错误无法安装vs2010,网上查找说与office07冲突……卸载后还是无法安装。 随后换成win7 32位,安装Framework4成功,可接下来遇到Object model失败,查了N久,无解,网上有人提出修改注册表RightOUT什么的,我是没见有谁用那个成功。偶然看到某些评论说是win7版本问题,原因不知。便更换了Lenovo的OEM版,重装vs2010。
May 15, 2010
ubuntu自动挂载NTFS分区
终端输入 sudo apt-get install ntfs-config sudo ntfs-config 然后就会弹出来一个对话框。 选择你需要挂载的分区,点应用,再选择"启用内部设备写支持"就可以了。
May 9, 2010
Linux下Eclipse设置汉字编码
今天把windows下的工程导入到了Linux下eclipse中,由于以前的工程代码,都是GBK编码的,而Ubuntu默认是不支持GBK编码的。所以,首先我们要先让Ubuntu支持GBK,方法如下:
May 9, 2010