精华内容
下载资源
问答
  • 东北轻合金有限责任公司针对 1560mm拉弯矫直机存在的电气系统故障高,可靠性差,而产品质量、尺寸精度是要求极高这一问题,决定应用新的数字系统对原可硅控制系统进行改造。新的系统采用了SIEMENS可编程控制器...
  • 东北轻合金有限责任公司针对 1560mm拉弯矫直机存在的电气系统故障高,可靠性差,而产品质量、尺寸精度是要求极高这一问题,决定应用新的数字系统对原可硅控制系统进行改造。新的系统采用了SIEMENS可编程控制器...
  • 本公众号知识分享:体系管理、质量管理、书籍教程;国标行标、团标企标;课件教材、系统培训、资料下载、以及部分软件及教程等; 告诉我您的需求,小编...2.0 适用范围:适用于本公司产品质量控制计划中出的测量系...

    dd5b146ccfa07e88082c71d83918c425.gif

    03e9839b31c86a93b00b20cce2e02605.png

    本公众号知识分享:体系管理、质量管理、书籍教程;国标行标、团标企标;课件教材、系统培训、资料下载、以及部分软件及教程等; 告诉我您的需求,小编随时恭候为您服务!

    79d299b2a7af9a8a712cf7f0b45e9012.png

    下面让我们一起开启本章内容学习!

    1.0 目的:

    程序定义公司测量系统分析方法, 了解测量变差来源,测量系统能否, 主要问题主要那里,针对问题采取纠正措施

    2.0 适用范围:

    适用于本公司产品质量控制计划列出测量系统。但是优先关注产品过程特殊特性以及关键工序相关控制

    3.0 定义:

    3.1稳定性:是测量系统在某持续时间内测量同一基准或零件的单一特性值时获得的测量值总变差。

    3.2 线性:是在量具预期的工作范围内,偏倚值的差值。     

    3.3 偏性:是测量结果的观测平均值与基准值的差值。

    3.4重复性:同一操作员使用同一测量仪器测量相同部分的同一特性时,多次测量结果的最大变差。

    3.5再现性:不同测量者使用相同的仪器测量某相同部分的同一特性时, 其测量平均值的最大变差。

    3.6 MSA测量系统分析(即:Measure System Analysis 的英文缩写)。

    3.7对于5性的分析,我司主要专注重复性和再现性的分析,除非客户的要求,我司一般不再进行偏倚,线性和稳定性的分析

    4.0 职责:

    4.1品质部:负责制定测量系统分析计划并组织实施

    4.2部门:负责配合品质部测量系统分析工作;

    5.0 工作程序:

    5.1测量系统分析(以后简称MSA)时机

    5.1.1初次分析应在生产正式提交PPAP之前进行

    5.1.2 一般实施一次MSA

    5.1.3 出现以下情况时,适当增加分析频次重新分析

    107f1761060f428acf7accb0c628fea3.png量具进行大修

    107f1761060f428acf7accb0c628fea3.png量具失准

    107f1761060f428acf7accb0c628fea3.png顾客需要

    107f1761060f428acf7accb0c628fea3.png重新提交PPAP

    107f1761060f428acf7accb0c628fea3.png测量系统发生变化

    5.2 MSA准备要求

    5.2.1制定MSA 计划主要包括以下内容:

    107f1761060f428acf7accb0c628fea3.png确定分析测量系统

    107f1761060f428acf7accb0c628fea3.png确定分析质量特性

    107f1761060f428acf7accb0c628fea3.png确定分析方法计量数据,采用均值极差计数数据,采用大小法,这里需要说明是,考虑公司实际规模情况,除非客户要求,我司进行技术数据的MSA.

    107f1761060f428acf7accb0c628fea3.png确定分析环境,尽可能使用实际测量环境

    107f1761060f428acf7accb0c628fea3.png确定分析人员测试人员

    107f1761060f428acf7accb0c628fea3.png确定样品数量重复读数次数

    5.2.2 量具准备

    107f1761060f428acf7accb0c628fea3.png针对质量特性, 选择作业指导或者工艺文件指定量具

    107f1761060f428acf7accb0c628fea3.png确保量具经过校准合格

    107f1761060f428acf7accb0c628fea3.png仪器量具分辨一般小于公差的1/10, 如果达到这一要求,请示上级,经过评估通过可以使用

    5.2.3 测试操作人员准备分析人员选择

    107f1761060f428acf7accb0c628fea3.png测试人员分析人员重叠

    107f1761060f428acf7accb0c628fea3.png优先选择平时岗位测试人员员工进行实际测试工作

    107f1761060f428acf7accb0c628fea3.png选择熟悉测试MSA分析人员作为分析人员

    5.2.4 分析样品选择

    107f1761060f428acf7accb0c628fea3.png样品必须实际生产检验过程选择,考虑可能代表生产存在所有产品变差

    107f1761060f428acf7accb0c628fea3.png样品编号,避免测试操作人员事先知道编号

    5.3 数据收集计算-计量数据重复性和再现性(R&R分析)

    5.3.1 数据收集

    107f1761060f428acf7accb0c628fea3.png随机抽取10个零件,确定某一尺寸/特性做为评价样本。

    107f1761060f428acf7accb0c628fea3.png对零件进行编号 1-10 ,编号应覆盖且不被操作员知道某一零件具体编号。

    107f1761060f428acf7accb0c628fea3.png指定3名操作员,每一个操作员单独地以随机的顺序选取零件,并对零件的尺寸/特性进行测量,负责组织此项研究的人员观察编号并在表格中对应记录数值。3个操作员测完一次后,再从头开始重复测量12次。

    107f1761060f428acf7accb0c628fea3.png将测量结果依次记录在《Gauge R & R Chart 上。

    5.3.2 数据计算

    因为GR&R表格设计时候已经公式设定好,数据输入后,结果自动算出, 这里重复

    5.3.3结果分析

    107f1761060f428acf7accb0c628fea3.pngX-R满足以下条件

    X50%以上上下控制之外

    R控制

    107f1761060f428acf7accb0c628fea3.png级数ndc>=5

    107f1761060f428acf7accb0c628fea3.pngG(R&R)接收准则:

    A.R&R% 10% 可接受

    B.10% ≦ R&R% ≦ 30% ,依量具的重要特性、成本及维修费用,决定是否接受。

    C.R&R% 30% 不能接受,必须改进;并通知客户知悉、协调处理对策,包括产品是否重新再测试。

    5.4 计数型量具-样法分析

    5.4.1 选取20零件和A,B 两名操作

    5.4.2 操作随机每个零件测量2次,NGG分别表示不合格合格”。

    5.4.3 结果进行分析评价

    6.0 质量记录

    6.1   测量系统分析计划》

    6.2   Gauge R & R Chart

    6.3   X -R Control Chart 管制图》

    d35aa2a670b5341a768c1a4cb6ec9daa.png

    db286ad49451a0ab17c47e9d75c81237.png

    免责声明

    本公众号部分文字、图片、音视频等内容摘自网络/用户投稿,旨在交流学习;其版权均属于原网或原著作人,任何单位/个人认为本平台内容,可能涉嫌侵犯其合法权益,请后台联系小编删除,非常感谢!

    d35aa2a670b5341a768c1a4cb6ec9daa.png

    资料共享

    本公众号资料,可通过发送标题/内容关键字获取!快来尝试一下吧!

       如:XX标准、XX教程、9001、内审员、质量文化、质量体系、........

    部分内容系统未能精准识别自动回复,小编会8小时内1对1回复,敬请耐心等候;谢谢!

    efbe770a09b351221f82c2d669194395.gif

    48c6cfa3bd25a143e01c12f7018d153d.png

    84ff5a9c43c39f7132ee1774c71bf3cf.gif

    展开全文
  • 德国iC-Haus GmbH公司日前针对数字马达控制,推出了快速12位编码器IC──iC-MH,这是针对极小空间磁性感测器应用的系统单芯片(SoC))解决方案,典型应用包括工业自动化及控制、机器人和汽车系统。  新元件结合了...
  • 上次将我需要的材料全部出来了,但是可能会有些变化。 在我做这个项目的过程中,根据遇到的实际情况来进行调整自己需要的具体模块。 本次将整个控制系统的控制逻辑简单写一下: 电机驱动器 我所用到的电机驱动器...

    上次将我需要的材料全部列出来了,但是可能会有些变化。
    在我做这个项目的过程中,根据遇到的实际情况来进行调整自己需要的具体模块。
    本次将整个控制系统的控制逻辑简单写一下:

    电机驱动器

    我所用到的电机驱动器就是根据在公司定制的电机配套的电机驱动器,如下
    在这里插入图片描述
    各个接口引脚说明如下
    在这里插入图片描述
    注意:其中的ALARM端子这里是控制器输出报警的引脚,给的使用手册上有问题。
    我主要是用到了其中的SV、F/R、EN、BAK、COM、端子。其中电机的电枢两端的电压是通过PWM进行调速,而转速反馈的信号本来是可以通过驱动器的SPEED接口输出的信号直接得到,但是不知道为什么这个端子的输出波形不是标准的方波信号,我通过示波器进行观察后,一直不能得到对自己有用的信号,所以最后我选择了通过与电机同轴连接一个增量式编码器来进行转速反馈(不带Z相的那种),最后得到了较好的结果。
    在前文中我提到处理转速信号我是通过将STM32单片机的引脚设置为外部触发的模式进行,但是现在我又发现一个问题,当我查到STM32F103ZET6的data sheet时,这款单片机只有三个外部触发模式的引脚,就是可以将定时器2、3、4设置为外部触发模式,通用定时器5是不可以设置的。所以我又不不得不改变我对于转速信号的处理方式,在本文中,我是通过将通用定时器设置为编码器接口模式来进行的。下面会介绍。

    原理图

    电机驱动模块


    中间的四个就是BLDC,我只是为了到时候连线方便,就通过AD画出了简单的原理图,处于两边的就是四个电机驱动器的简化图。

    编码器模块

    在这里插入图片描述
    通过四个增量式编码器得到转速反馈信号。

    接收器模块

    在这里插入图片描述
    接收器模块主要是通过工业遥控器模块来进行对整个割草机进行控制,根据控制继电器的通断,当STM32F103ZET6单片机得到对应的电平信号后,在内部进行处理得到相应的电机控制信号。
    注:单片机对于使用者还是要有一定的使用基础,要是连最基本的跑马灯都不会的话,最好还是先学一下,我觉得使用标准库还是HAL库没有特别大的区别,主要看个人的习惯,要是想要偷懒或者怎样,HAL是一个不错的选择,但是怎么样实现自己的控制逻辑还是要自己写。最好还是老老实实的自己写,不仅可以熟练使用KEIL软件,还可以更加理解标准库的结构,内部函数的调用过程(以上全是个人看法,不要争,争就是你赢。)

    单片机的配置

    1、基本定时器配置
    基本定时器我在这主要是用来在定时器中断函数中读取各个编码器的编码值。
    还有就是几种定时器的区别一定要好好看看data sheet(数据手册),不然以为自己是对的,但在调试过程中,不知道在哪就错了

    基本定时器配置

    基本定时器中断配置
    static void BASIC_TIM_NVIC_Config(void)
    {
        NVIC_InitTypeDef NVIC_InitStructure; 
        // ÉèÖÃÖжÏ×éΪ0
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);		
    		// ÉèÖÃÖжÏÀ´Ô´
        NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;	
    		// ÉèÖÃÖ÷ÓÅÏȼ¶Îª 0
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	 
    	  // ÉèÖÃÇÀÕ¼ÓÅÏȼ¶Îª3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;	
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    }
    基本定时器的配置
    static void BASIC_TIM_Config(void)
    {
    		TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    		
    		// ¿ªÆô¶¨Ê±Æ÷ʱÖÓ,¼´ÄÚ²¿Ê±ÖÓCK_INT=72M
        BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);
    	
    		// ×Ô¶¯ÖØ×°ÔؼĴæÆ÷µÄÖµ£¬ÀÛ¼ÆTIM_Period+1¸öƵÂʺó²úÉúÒ»¸ö¸üлòÕßÖжÏ
        TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period;	
    
    	  // ʱÖÓÔ¤·ÖƵÊýΪ
        TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler;
    	
    	
        TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);
    		
    		// Çå³ý¼ÆÊýÆ÷Öжϱê־λ
        TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);
    	  
    		// ¿ªÆô¼ÆÊýÆ÷ÖжÏ
        TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);
    		
    		// ʹÄܼÆÊýÆ÷
        TIM_Cmd(BASIC_TIM, ENABLE);
    }
    
    

    通用定时器配置

    编码器模式对应的IO引脚配置
    void GPIO_TIM5_Encoder_Init(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(MOTOR_ENCODER_LEFT_FRONT_CLK, ENABLE);
    	GPIO_InitStruct.GPIO_Pin=MOTOR_ENCODER_LEFT_FRONT_A|MOTOR_ENCODER_LEFT_FRONT_B;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;///±àÂëÆ÷ģʽ¶ÔÓ¦Òý½ÅÉèÖÃΪ¸¡¿ÕÊäÈëģʽ
    	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_Init(MOTOR_ENCODER_LEFT_FRONT_PORT,&GPIO_InitStruct);
    }
    
    定时器的配置
    void TIM5_Config(void)
    {
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstructure;
    	
    	TIM_ICInitTypeDef  TIM_ICInitTypetructure;
    	TIM_TimeBaseStructInit(&TIM_TimeBaseInitstructure);
    	TIM_TimeBaseInitstructure.TIM_ClockDivision=0;
    	TIM_TimeBaseInitstructure.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_TimeBaseInitstructure.TIM_Period=65535-1;
    	TIM_TimeBaseInitstructure.TIM_Prescaler=0;
    	
    	/*³õʼ»¯¶¨Ê±Æ÷2*/
    	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitstructure);
    	
    	 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
    	/*ÅäÖñàÂëÆ÷ģʽ½Ó¿Ú*/
    	/*¶¨Ê±Æ÷2ÉèÖÃΪ±àÂëÆ÷ģʽ£¬Á½¸ö·½Ïò£¬Ï½µÑز¶»ñ*/
    	TIM_EncoderInterfaceConfig(TIM5,TIM_EncoderMode_TI12,TIM_ICPolarity_Falling,TIM_ICPolarity_Falling);
    	/*ÌîÈëȱʡֵ*/
    	TIM_ICStructInit(&TIM_ICInitTypetructure);
    	TIM_ICInitTypetructure.TIM_ICFilter=6;
    	TIM_ICInit(TIM5, &TIM_ICInitTypetructure);
    	
    	//¼ÆÊýÆ÷ÊýÖµ³õʼ»¯
    	TIM_SetCounter(TIM5, 32768);
    	
    	/*¶¨Ê±Æ÷ʹÄÜ*/
    	TIM_Cmd(TIM5, ENABLE);
    }
    其他的定时器类似,不在赘述
    

    获取编码值

    一般就是通过这样的方式得到编码器的值,注意自己设置的计数器内部的初值是多少,还有在配置编码器接口模式的时候是否经过倍频处理,这些过程对于处理最后的转速反馈计算都是必不可少的过程。
    int Read_encoder_value(uint16_t TIMX)
    {
    	
    	switch (TIMX)
    	{
    		case 2:
    			encoder_TIM2_speed=TIM2->CNT-32768;
    			break;
    		case 3:
    			encoder_TIM3_speed=TIM3->CNT-32768;
    			break;
    	  case 4:
    			encoder_TIM4_speed=TIM4->CNT-32768;
    			break;
    		case 5:
    			encoder_TIM5_speed=TIM5->CNT-32768;
    			break;
    	}
    	return 0;
    }
    

    IO引脚配置

    这里就是通过遥控接收器的继电器的通断使得IO引脚获得的电平信号

    void motor_front_normal_recieve(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(MOTOR_FRONT_NORMAL_GPIO_PIN_READ_CLK, ENABLE);
    	GPIO_InitStruct.GPIO_Pin=MOTOR_FRONT_NORMAL_GPIO_PIN_READ;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//ÅäÖÃΪÉÏÀ­ÊäÈ룬¸´Î»Ä¬ÈÏΪ1
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(MOTOR_FRONT_NORMAL_GPIO_PIN_READ_PORT, &GPIO_InitStruct);	
    }
    
    
    void motor_front_add_recieve(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(MOTOR_FRONT_ADD_GPIO_PIN_READ_CLK, ENABLE);
    	GPIO_InitStruct.GPIO_Pin=MOTOR_FRONT_ADD_GPIO_PIN_READ;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//ÅäÖÃΪÉÏÀ­ÊäÈ룬¸´Î»Ä¬ÈÏΪ1;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(MOTOR_FRONT_ADD_GPIO_PIN_READ_PORT, &GPIO_InitStruct);	
    }
    
    
    void motor_front_sub_recieve(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(MOTOR_FRONT_SUB_GPIO_PIN_READ_CLK, ENABLE);
    	GPIO_InitStruct.GPIO_Pin=MOTOR_FRONT_SUB_GPIO_PIN_READ;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//ÅäÖÃΪÉÏÀ­ÊäÈ룬¸´Î»Ä¬ÈÏΪ1;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(MOTOR_FRONT_SUB_GPIO_PIN_READ_PORT, &GPIO_InitStruct);	
    }
    
    
    void motor_left_front_recieve(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(MOTOR_LEFT_FRONT_GPIO_PIN_READ_CLK, ENABLE);
    	GPIO_InitStruct.GPIO_Pin=MOTOR_LEFT_FRONT_GPIO_PIN_READ;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//ÅäÖÃΪÉÏÀ­ÊäÈ룬¸´Î»Ä¬ÈÏΪ1;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(MOTOR_LEFT_FRONT_GPIO_PIN_READ_PORT, &GPIO_InitStruct);	
    }
    
    
    void motor_right_front_recieve(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(MOTOR_RIGHT_FRONT_GPIO_PIN_READ_CLK, ENABLE);
    	GPIO_InitStruct.GPIO_Pin=MOTOR_RIGHT_FRONT_GPIO_PIN_READ;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//ÅäÖÃΪÉÏÀ­ÊäÈ룬¸´Î»Ä¬ÈÏΪ1;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(MOTOR_RIGHT_FRONT_GPIO_PIN_READ_PORT, &GPIO_InitStruct);	
    }
    
    
    void motor_back_recieve(void)
    {
    	GPIO_InitTypeDef  GPIO_InitStruct;
    	RCC_APB2PeriphClockCmd(MOTOR_BACK_GPIO_PIN_READ_CLK, ENABLE);
    	GPIO_InitStruct.GPIO_Pin=MOTOR_BACK_GPIO_PIN_READ;
    	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//ÅäÖÃΪÉÏÀ­ÊäÈ룬¸´Î»Ä¬ÈÏΪ1;
    	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(MOTOR_BACK_GPIO_PIN_READ_PORT, &GPIO_InitStruct);	
    }
    

    注:32单片机的引脚模式配置有几种,根据需要自己配置,最开始我将所有的我需要的IO引脚均配置为上拉输入模式,但是有几个引脚我通过万用表测到的初始引脚电平并不是3.3V,我查了原因,但是没有查到,然后我通过将其中的几个引脚配置为浮空输入模式,这种模式下IO引脚的电平根据外部电路决定的,当然我为了达到让IO引脚有上拉的效果,我在外围电路还是一个上拉电阻接在上面。最后实现了我的目的。

    引脚电平判断函数

    
    uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
    {
    	//ʵ¼Ê½ÓÏßÊÇÅжϵ͵çƽÀ´µÃµ½½á¹ûÖ´Ðнá¹û
    	//Èç¹ûÒ£¿Ø°¸°´¼ü°´Ï£¬¼´µÃµ½µÍµçƽµÄ½á¹û£¬·µ»Ø1£»·ñÔò·µ»Ø0
    	if( GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_OFF )
    	{
    		
    		return KEY_ON;
    	}
    	else return KEY_OFF;
    }
    所有的变量我都是通过宏定义实现的,主要是为了以后要是用的到的话方便移植代码,我觉得这样也是一个较好的习惯(对我个人来讲)
    

    查询外部电平引脚函数

    主要是在主函数的while循环中实现一直查询,根据电平执行函数。这里是结合了处理转速反馈以及电平值得获取以及PID调整的整个过程,就只有一个简单的转速闭环,还没有涉及到内部的电流跟踪控制,相信以后有机会我也会将这个贴出来的。

    void Look_Up_GPIO(void)
    {
    	//°´ÏÂ1ºÅ°´¼ü£¬µç»ú³£ËÙÇ°½ø
    	/*ÕâÀï¼ÓÉÏÒ»Ìõ¼þÅжÏÓï¾ä£¬Èç¹û¶ÁÈ¡Ç°½øº¯Êý¶ÔÓ¦µÄÍⲿ½ÓÊÕÒý½ÅΪ0£¬Õ⿪ʼµ÷ÓÃÇ°½øº¯Êý£¬º¯ÊýµÄ·µ»ØֵΪ1*/
    	if(Key_Scan(MOTOR_FRONT_NORMAL_GPIO_PIN_READ_PORT,MOTOR_FRONT_NORMAL_GPIO_PIN_READ))
    	{
    		//Èç¹û¶ÔÓ¦µÄÒý½Åµçƽ==0£¬µç»ú³£ËÙÇ°½ø
    		formal_speed_front();
    		
    		//¶ÁÈ¡¶ÔÓ¦±àÂëÆ÷µÄÊý¾Ý
    		Read_encoder_value(2); 
    		Read_encoder_value(3);
    		Read_encoder_value(4);
    		Read_encoder_value(5);
    		
    		//¿ªÊ¼½øÐÐPID²ÎÊýµÄµ÷Õû
    		//×¢£º´Ë´¦µÄ2000ÊÇûÓп¼Âǵç»ú¼õËٱȵĽá¹û£¬Õý³£Çé¿öÏÂÊÇ2000/k,ÆäÖÐKÊǵç»ú±¾ÉíµÄ¼õËÙ±È
    		/*µÃµ½Ëĸöµç»úµÄÓ¦¸ÃÊä³öµÄʵ¼ÊÕ¼¿Õ±È£¬Ç¿ÖÆת»»ÎªÕûÐÍ*/
    		//×¢Ò⣬ÕâÀïÐèÒª½«µÃµ½µÄ±àÂëÆ÷Êý¾Ý*10£¬ÒòΪÊÇÔÚ10ms¿ªÊ¼¸üÐÂÖжϣ¬×îºóÔÚÖжϴ¦Àíº¯ÊýÖн«Êý¾Ý¸üУ¬Í¬Ê±ÇåÁã¼ÆÊýÆ÷µÄ³õÖµ
    		encoder_TIM2_speed_deltak=(int)Actually_Speed(encoder_TIM2_speed*10,normal_speed);
    		
    		encoder_TIM3_speed_deltak=(int)Actually_Speed(encoder_TIM3_speed*10,normal_speed);
    		
    		encoder_TIM4_speed_deltak=(int)Actually_Speed(encoder_TIM4_speed*10,normal_speed);
    		
    		encoder_TIM5_speed_deltak=(int)Actually_Speed(encoder_TIM5_speed*10,normal_speed);
    		
    		/*¶ÔËÄ·PWMÖØи³Öµ£¬Í¨¹ý»ù±¾¶¨Ê±Æ÷µÄ¸üÐÂÖжÏÀ´¶ÔÂö³åÕ¼¿Õ±È½øÐÐÖØи³Öµ£¬´úÂëÔÚstm32f10x_it.cÎļþ*/
    	}
    	else if(Key_Scan(MOTOR_FRONT_ADD_GPIO_PIN_READ_PORT,MOTOR_FRONT_ADD_GPIO_PIN_READ))
    	{
    		//´Ë´¦°´ÏÂ2ºÅ°´¼ü£¬
    		//Èç¹û¶ÔÓ¦µÄÒý½Åµçƽ==0£¬µç»ú¼ÓËÙÇ°½ø
    		add_speed_front();
    		
    		//¶ÁÈ¡¶ÔÓ¦±àÂëÆ÷µÄÊý¾Ý
    		Read_encoder_value(2);
    		Read_encoder_value(3);
    		Read_encoder_value(4);
    		Read_encoder_value(5);
    		
    		//¿ªÊ¼½øÐÐPID²ÎÊýµÄµ÷Õû
    		//×¢£º´Ë´¦µÄ2000ÊÇûÓп¼Âǵç»ú¼õËٱȵĽá¹û£¬Õý³£Çé¿öÏÂÊÇ2000/k,ÆäÖÐKÊǵç»ú±¾ÉíµÄ¼õËÙ±È
    		/*µÃµ½Ëĸöµç»úµÄÓ¦¸ÃÊä³öµÄʵ¼ÊÕ¼¿Õ±È£¬Ç¿ÖÆת»»ÎªÕûÐÍ*/
    		encoder_TIM2_speed_deltak=(int)Actually_Speed(encoder_TIM2_speed,add_speed);
    		
    		encoder_TIM3_speed_deltak=(int)Actually_Speed(encoder_TIM3_speed,add_speed);
    		
    		encoder_TIM4_speed_deltak=(int)Actually_Speed(encoder_TIM4_speed,add_speed);
    		
    		encoder_TIM5_speed_deltak=(int)Actually_Speed(encoder_TIM5_speed,add_speed);
    		
    		/*¶ÔËÄ·PWMÖØи³Öµ£¬Í¨¹ý»ù±¾¶¨Ê±Æ÷µÄ¸üÐÂÖжÏÀ´¶ÔÂö³åÕ¼¿Õ±È½øÐÐÖØи³Öµ£¬´úÂëÔÚstm32f10x_it.cÎļþ*/
    	}
    	else if(Key_Scan(MOTOR_FRONT_SUB_GPIO_PIN_READ_PORT,MOTOR_FRONT_SUB_GPIO_PIN_READ))
    	{
    		
    		//°´ÏÂ3ºÅ°´¼ü£¬µç»ú¼õËÙÇ°½ø
    		//Èç¹û¶ÔÓ¦µÄÒý½Åµçƽ==0£¬µç»ú¼õËÙÇ°½ø
    		sub_speed_front();
    		
    		//¶ÁÈ¡¶ÔÓ¦±àÂëÆ÷µÄÊý¾Ý
    		Read_encoder_value(2);
    		Read_encoder_value(3);
    		Read_encoder_value(4);
    		Read_encoder_value(5);
    		
    		//¿ªÊ¼½øÐÐPID²ÎÊýµÄµ÷Õû
    		//×¢£º´Ë´¦µÄ2000ÊÇûÓп¼Âǵç»ú¼õËٱȵĽá¹û£¬Õý³£Çé¿öÏÂÊÇ2000/k,ÆäÖÐKÊǵç»ú±¾ÉíµÄ¼õËÙ±È
    		/*µÃµ½Ëĸöµç»úµÄÓ¦¸ÃÊä³öµÄʵ¼ÊÕ¼¿Õ±È£¬Ç¿ÖÆת»»ÎªÕûÐÍ*/
    		encoder_TIM2_speed_deltak=(int)Actually_Speed(encoder_TIM2_speed,sub_speed);
    		
    		encoder_TIM3_speed_deltak=(int)Actually_Speed(encoder_TIM3_speed,sub_speed);
    		
    		encoder_TIM4_speed_deltak=(int)Actually_Speed(encoder_TIM4_speed,sub_speed);
    		
    		encoder_TIM5_speed_deltak=(int)Actually_Speed(encoder_TIM5_speed,sub_speed);
    		
    		/*¶ÔËÄ·PWMÖØи³Öµ£¬Í¨¹ý»ù±¾¶¨Ê±Æ÷µÄ¸üÐÂÖжÏÀ´¶ÔÂö³åÕ¼¿Õ±È½øÐÐÖØи³Öµ£¬´úÂëÔÚstm32f10x_it.cÎļþ*/
    	}
    	else if(Key_Scan(MOTOR_BACK_GPIO_PIN_READ_PORT,MOTOR_BACK_GPIO_PIN_READ))
    	{
    		//¶ÔÓ¦°´ÏÂ4ºÅ°´¼ü£¬µç»úºóÍË
    		//Èç¹û¶ÔÓ¦µÄÒý½Åµçƽ==0£¬µç»úºóÍË
    		motor_back();
    		
    		//¶ÁÈ¡¶ÔÓ¦±àÂëÆ÷µÄÊý¾Ý
    		Read_encoder_value(2);
    		Read_encoder_value(3);
    		Read_encoder_value(4);
    		Read_encoder_value(5);
    		
    		//¿ªÊ¼½øÐÐPID²ÎÊýµÄµ÷Õû
    		//×¢£º´Ë´¦µÄ2000ÊÇûÓп¼Âǵç»ú¼õËٱȵĽá¹û£¬Õý³£Çé¿öÏÂÊÇ2000/k,ÆäÖÐKÊǵç»ú±¾ÉíµÄ¼õËÙ±È
    		/*µÃµ½Ëĸöµç»úµÄÓ¦¸ÃÊä³öµÄʵ¼ÊÕ¼¿Õ±È£¬Ç¿ÖÆת»»ÎªÕûÐÍ*/
    		encoder_TIM2_speed_deltak=(int)Actually_Speed(encoder_TIM2_speed,back_speed);
    		
    		encoder_TIM3_speed_deltak=(int)Actually_Speed(encoder_TIM3_speed,back_speed);
    		
    		encoder_TIM4_speed_deltak=(int)Actually_Speed(encoder_TIM4_speed,back_speed);
    		
    		encoder_TIM5_speed_deltak=(int)Actually_Speed(encoder_TIM5_speed,back_speed);
    		
    		/*¶ÔËÄ·PWMÖØи³Öµ£¬Í¨¹ý»ù±¾¶¨Ê±Æ÷µÄ¸üÐÂÖжÏÀ´¶ÔÂö³åÕ¼¿Õ±È½øÐÐÖØи³Öµ£¬´úÂëÔÚstm32f10x_it.cÎļþ*/
    	}
    	else if(Key_Scan(MOTOR_LEFT_FRONT_GPIO_PIN_READ_PORT,MOTOR_LEFT_FRONT_GPIO_PIN_READ))
    	{
    		//¶ÔÓ¦°´ÏÂ5ºÅ°´¼ü£¬µç»ú×óÇ°Ô˶¯
    		//Èç¹û¶ÔÓ¦µÄÒý½Åµçƽ==0£¬µç»ú×óÇ°
    		motor_left_front();
    		
    		//¶ÁÈ¡¶ÔÓ¦±àÂëÆ÷µÄÊý¾Ý
    		Read_encoder_value(2);
    		Read_encoder_value(3);
    		Read_encoder_value(4);
    		Read_encoder_value(5);
    		
    		//¿ªÊ¼½øÐÐPID²ÎÊýµÄµ÷Õû
    		//×¢£º´Ë´¦µÄ2000ÊÇûÓп¼Âǵç»ú¼õËٱȵĽá¹û£¬Õý³£Çé¿öÏÂÊÇ2000/k,ÆäÖÐKÊǵç»ú±¾ÉíµÄ¼õËÙ±È
    		/*µÃµ½Ëĸöµç»úµÄÓ¦¸ÃÊä³öµÄʵ¼ÊÕ¼¿Õ±È£¬Ç¿ÖÆת»»ÎªÕûÐÍ*/
    		encoder_TIM2_speed_deltak=(int)Actually_Speed(encoder_TIM2_speed,left_front_speed);
    		
    		encoder_TIM3_speed_deltak=(int)Actually_Speed(encoder_TIM3_speed,left_front_speed);
    		
    		encoder_TIM4_speed_deltak=(int)Actually_Speed(encoder_TIM4_speed,stop_speed);
    		
    		encoder_TIM5_speed_deltak=(int)Actually_Speed(encoder_TIM5_speed,stop_speed);
    		
    		/*¶ÔËÄ·PWMÖØи³Öµ£¬Í¨¹ý»ù±¾¶¨Ê±Æ÷µÄ¸üÐÂÖжÏÀ´¶ÔÂö³åÕ¼¿Õ±È½øÐÐÖØи³Öµ£¬´úÂëÔÚstm32f10x_it.cÎļþ*/
    	}
    	
    	else if(Key_Scan(MOTOR_RIGHT_FRONT_GPIO_PIN_READ_PORT,MOTOR_RIGHT_FRONT_GPIO_PIN_READ))
    	{
    		//¶ÔÓ¦°´ÏÂ6ºÅ°´¼ü£¬µç»úÓÒÇ°Ô˶¯
    		//Èç¹û¶ÔÓ¦µÄÒý½Åµçƽ==0£¬µç»úÓÒÇ°
    		motor_right_front();
    		 
    		//¶ÁÈ¡¶ÔÓ¦±àÂëÆ÷µÄÊý¾Ý
    		Read_encoder_value(2);
    		Read_encoder_value(3);
    		Read_encoder_value(4);
    		Read_encoder_value(5);
    		
    		//¿ªÊ¼½øÐÐPID²ÎÊýµÄµ÷Õû
    		//×¢£º´Ë´¦µÄ2000ÊÇûÓп¼Âǵç»ú¼õËٱȵĽá¹û£¬Õý³£Çé¿öÏÂÊÇ2000/k,ÆäÖÐKÊǵç»ú±¾ÉíµÄ¼õËÙ±È
    		/*µÃµ½Ëĸöµç»úµÄÓ¦¸ÃÊä³öµÄʵ¼ÊÕ¼¿Õ±È£¬Ç¿ÖÆת»»ÎªÕûÐÍ*/
    		//encoder_TIM2_speedÊǾ­¹ýËı¶ÆµºóµÄ±àÂëÂö³å¸öÊý£¬¶øʵ¼ÊתËÙÓ¦/4
    		encoder_TIM2_speed_deltak=(int)Actually_Speed(encoder_TIM2_speed/4,stop_speed);
    		
    		encoder_TIM3_speed_deltak=(int)Actually_Speed(encoder_TIM3_speed/4,stop_speed);
    		
    		encoder_TIM4_speed_deltak=(int)Actually_Speed(encoder_TIM4_speed/4,right_front_speed);
    		
    		encoder_TIM5_speed_deltak=(int)Actually_Speed(encoder_TIM5_speed/4,right_front_speed);
    		
    		/*¶ÔËÄ·PWMÖØи³Öµ£¬Í¨¹ý»ù±¾¶¨Ê±Æ÷µÄ¸üÐÂÖжÏÀ´¶ÔÂö³åÕ¼¿Õ±È½øÐÐÖØи³Öµ£¬´úÂëÔÚstm32f10x_it.cÎļþ*/
    	}
    }
    

    PID控制

    这里我用的是经典的PID控制,这种在工业控制上占比达到90%以上的控制算法是值得借鉴的。其中的PID参数根据自己的实际情况进行整定。

    uint16_t set_speed;
    
    /*¶¨ÒåÒ»¸ö±£´æÕ¼¿Õ±ÈµÄÈ«¾Ö±äÁ¿*/
    uint16_t delta_k;
    
    void PID_Init(void)
    {
    	pid actuall;
    	actuall.ExpectedValue = 0;
    	actuall.ActualValue = 0.0;
    	actuall.err = 0.0;
    	actuall.err_prev = 0.0;
    	actuall.err_last = 0.0;
    	//±ÈÀý³£ÊýºÍ»ý·Ö³£Êý¸ù¾Ýʵ¼ÊÇé¿ö½øÐе÷ÕûµÃµ½£¬ÕâÀï²»ÊÇÒ»¶¨µÄ½á¹û
    	actuall.Kp = 10;
    	actuall.Ki = 0.2;
    	actuall.Kd = 0.0;
    }
    
    double PID_Realize(double present_speed,double gain_speed)
    {
    	
    	pid actuall;
    	double incrementValue;
    	actuall.ExpectedValue = gain_speed;
    	actuall.ActualValue = present_speed;
    	actuall.err = actuall.ExpectedValue - actuall.ActualValue;
    	
    
    	incrementValue = actuall.Kp*(actuall.err - actuall.err_last) + actuall.Ki*(actuall.err) + actuall.Kd*(actuall.err - 2 * actuall.err_last + actuall.err_prev);
    	
    
    	actuall.ActualValue += incrementValue;
    	
    	//½«Ç°Ò»´ÎµÄÆ«²î±£Áô
    	actuall.err_prev = actuall.err_last;
    	actuall.err_last = actuall.err;
    	
    	//·µ»ØµÃµ½µÄʵ¼ÊֵתËÙ
    	return actuall.ActualValue;
    }
    float Actually_Speed(double present_speed,double gain_speed)
    {
    
    	set_speed=(int)PID_Realize(present_speed,gain_speed);
    	
    	delta_k=set_speed/4000;
    	
    	return (float)delta_k*500;
    }
    

    主函数代码

    int main(void)
    {
    	MOTOR_LEFT_FRONT_GPIO_Config();
    	MOTOR_RIGHT_FRONT_GPIO_Config();
    	MOTOR_LEFT_BACK_GPIO_Config();
    	MOTOR_RIGHT_BACK_GPIO_Config();
    	
    	LED_Init();
    
    	BASIC_TIM_Init();
    	/*¸ß¼¶¶¨Ê±Æ÷³õʼ»¯*/
    	ADVANCE_TIM_Init();
    	MOTOR_LEFT_FRONT_SET_PWM;
    	MOTOR_LEFT_BACK_SET_PWM;
    	MOTOR_RIGHT_FRONT_SET_PWM;
    	MOTOR_RIGHT_BACK_SET_PWM;
    	/*½«Í¨Óö¨Ê±Æ÷µÄÍⲿ´¥·¢Òý½ÅÉèÖÃΪÂö³å¼ÆÊýģʽ£¬ÏÂÃæÊdzõʼ»¯º¯Êý*/
    
    	//¶¨Ê±Æ÷5±àÂëÆ÷ģʽ³õʼ»¯
    	GPIO_TIM5_Encoder_Init();
    	TIM5_Config();
    	//¶¨Ê±Æ÷4±àÂëÆ÷ģʽ³õʼ»¯
    	GPIO_TIM4_Encoder_Init();
    	TIM4_Config();
    	//¶¨Ê±Æ÷3±àÂëÆ÷ģʽ³õʼ»¯
    	GPIO_TIM3_Encoder_Init();
    	TIM3_Config();
    	//¶¨Ê±Æ÷2±àÂëÆ÷ģʽ³õʼ»¯
    	GPIO_TIM2_Encoder_Init();
    	TIM2_Config();	
    	/*¶ÔºìÍâÒ£¿ØµÄ½ÓÊÕÒý½Å½øÐгõʼ»¯£¬×¼±¸ÅжϽÓÊÕµçƽ±ä»¯*/
    	recieve_GPIO();
    	while(1)
    	{
    			Look_Up_GPIO();
    	}
    }
    

    到这里基本的控制代码就差不多实现了,具体结果怎么样还要我根据实际调试的结果来看是否需要对某些环节的代码进行修改。最近我看了一部电影,讲的是爱迪生与特斯拉的交直流战争,而且最近我也在重新学习一些电力电子相关的内容,真的好看啊,虽然没有漫威那样激烈的名场面,但是对于不断在进步的我们,学习之余,了解一些人类进步的历史,也是一种别样的休息方式。各位,下次再见喽!

    展开全文
  • IBM公司的销售系统

    2010-09-20 12:33:49
    因此在1965年该公司决定,开发一个处理订货单的系统。随着要求的不断提高,系统的不断完善。现在的AAS系统巳经成了一个具有多种管理功能、控制着世界上许多地区和分支的大型的管理信息系统。  从订单处理入手,他们...
  • 为什么说数据库版本控制是必须的

    万次阅读 多人点赞 2014-05-08 15:43:27
    前言 开发过程中的版本控制非常常见,但在数据库的世界来说...我任职过的几家公司在开发流程中的版本控制做的非常到位,但数据库方面却是一片空白,在开发过程中,经常会涉及到表上增加、修改、修改存储过程和视图
    原文出处:黄钊吉CSDN博客:为什么说数据库版本控制是必要的

    前言


    开发过程中的版本控制非常常见,但在数据库的世界来说,版本控制就是二等甚至三等公民了。当多人同时开发一个数据库管理和应用系统时,采用合理的方法监控数据库中表、存储过程和视图等对象的变动是非常重要的,每次更改数据库,都需要做详细的记录,稍不留神就出问题。我任职过的几家公司在开发流程中的版本控制做的非常到位,但数据库方面却是一片空白,在开发过程中,经常会涉及到表上增加列、修改列、修改存储过程和视图,发生变化后,之前的数据库对象定义就丢失了,给开发带来非常多的麻烦,下面说说我解决没有数据库版本控制机制所引起的麻烦的思路。

     

    备份数据库


    解决这个麻烦我们最开始的思路就是备份数据库,每隔几天备份一次数据库,当需要找历史数据库对象时将备份库还原到测试机上再把对应的存储过程或者表定义找出来。这种方式使用过程中就发现很多问题,首先每次需要查看历史记录的时候去还原备份非常麻烦,其次随着开发的进行,很难记得清是谁在什么时间改了什么数据库对象,必须把一段时间内的备份都还原了再进行查找。这个过程不仅让人很恼火,也非常浪费时间精力,如果备份间隔过长,期间变更的对象定义就无法找回了。

     

    导出数据库对象


    后来的解决思路就是每次修改数据库对象的时候将数据库对象的定义以.sql的方式存入SVN,这种方式非常麻烦。很多时候开发人员偷懒忘记签入SVN了,则会引起很大问题。新加入团队的人也很难看清版本修改的来龙去脉。此外,这种方式非常不直观,如果希望看到一个数据库对象的历史版本记录,则还要去SVN中查找,显示也非常不直观

            还有一个问题是团队中的开发DBA非常不习惯使用SVN。

     

    将版本记录存入数据库


    这种方式是我在网上看到过的,是在数据库中通过触发器对于数据库的变更操作进行记录,作为开发出身的人来说,对这种方式就不是很喜欢。况且去历史表中找版本修改记录本来就是一件费时费力的事。

     

    使用第三方工具


    现在一些第三方公司已经开发了针对数据库的版本控制工具,我们之前曾经尝试过RedGate的SQLSource Control(http://www.red-gate.com/products/sql-development/sql-source-control/),SQLSource Control的原理是基于SVN,使用起来不是很符合团队的使用习惯,易用性不够,在团队推广的培训成本也比较高。


    最近团队在使用的另一个工具是一个很易用的中文版数据库版本控制软件,叫做SourceSafe for SQL Server(http://www.grqsh.com/products.htm?tab=sourcesafe-for-sql-server), Source Safe for SQL Server的原理是将变更记录存入版本库,定期可以将数据库定义的脚本导入SVN,数据库版本的历史记录可以像在SVN中那样查看,团队推广的培训成本也比较低。帮助我们解决了很多团队中的问题。


     

     

    后记


    数据库版本化看似是个可有可无的过程,但做好了,可以减少开发和实施甚至是生产环境中的很多麻烦,我们的系统就是个活生生的例子。本文所阐述的方法是来自之前团队的经验。开发团队的发展都会经历从幼稚到成熟,借鉴成熟工具的经验和方法论,提前认识并解决问题可减少损失提升生产力。

    展开全文
  • 我们经常需要实现灵活配置数据的访问权限控制,例如只有某些用户可以看到“开户行,银行帐户,公司税号”等字段,其他用户都不能访问,也不能查看这几个字段,类似的需求在通用权限管理系统里是如何实现的?...

    我们经常需要实现灵活配置数据列的访问权限控制,例如只有某些用户可以看到“开户行,银行帐户,公司税号”等字段,其他用户都不能访问,也不能查看这几个字段,类似的需求在通用权限管理系统里是如何实现的? 我们以图文的方式把主要实现流程讲解给大家。

       通用权限里追求的理念是,不依赖某个开发人员尽量能用工具实现,能重复利用,能经得起推敲,函数源码可以重复利用,不管是才C\S, B\S 都可以重复利用的强大函数库,不用总是推倒重来的严格数据库架构,同时还可以兼容多种数据库的目标,打造一个一劳永逸的通用权限管理系统,成为主流各种信息管理系统的核心第3方系统组件,我们不主张去做任何一个项目,但是我们的组件可以用在任何信息化项目里,我们为成千上万的开发商提供服务。  

       程序的运行效果如下:

    吉日嘎拉,通用权限管理系统组件

    这个是通过调用列权限服务的SOA模式调用,然后对界面的表格数据进行一些处理,

    1:把表格列过滤为只能访问的列。

    2:把可编辑的权限的列进行设置。

    3:把拒绝访问的列也可以剔除掉(参考)。

                // 这里是按列的数据权限的权限进行数据绑定的例子代码
                
    // 这里是当前用户能访问的列名
                TableColumnsService tableColumnsService = new TableColumnsService();
                string[] accessColumns = tableColumnsService.GetColumns(this.UserInfo, BaseBusinessCardTable.TableName, "Column.Access");
                // 设置为只能访问的列
                BaseInterfaceLogic.SetColumns(this.grdBusinessCard, accessColumns);

                string[] editColumns = tableColumnsService.GetColumns(this.UserInfo, BaseBusinessCardTable.TableName, "Column.Edit");
                // 设置为可编辑列
                BaseInterfaceLogic.SetEditColumns(this.grdBusinessCard, editColumns);

                // 拒绝访问的权限列名获取
                string[] deneyColumns = tableColumnsService.GetColumns(this.UserInfo, BaseBusinessCardTable.TableName, "Column.Deney");
                BaseInterfaceLogic.RemoveColumns(this.grdBusinessCard, deneyColumns);

     

    这里是控制表格的参考函数

            public static void SetColumns(DataGridView dataGridView, string[] columns)
            {
                for (int i = dataGridView.Columns.Count - 1; i > 0; i--)
                {
                    if (dataGridView.Columns[i].DataPropertyName.Equals("Selected"))
                    {
                        break;
                    }
                    if (!BaseBusinessLogic.Exists(columns, dataGridView.Columns[i].DataPropertyName))
                    {
                        dataGridView.Columns.RemoveAt(i);
                    }
                }
            }

            public static void SetEditColumns(DataGridView dataGridView, string[] columns)
            {
                for (int i = 0; i < dataGridView.Columns.Count; i++)
                {
                    if (BaseBusinessLogic.Exists(columns, dataGridView.Columns[i].DataPropertyName))
                    {
                        dataGridView.Columns[i].ReadOnly = false;
                        dataGridView.Columns[i].DefaultCellStyle.BackColor = Color.FromArgb(255255128);
                    }
                }
            }

            public static void RemoveColumns(DataGridView dataGridView, string[] columns)
            {
                for (int i = dataGridView.Columns.Count-1; i >0 ; i--)
                {
                    if (BaseBusinessLogic.Exists(columns, dataGridView.Columns[i].DataPropertyName))
                    {
                        dataGridView.Columns.RemoveAt(i);
                    }
                }
            }

     

    我们想顺利的实现数据字段的权限,需要进行一下系统性的步骤:

    1:首先需要用数据库模型设计工具设计好数据库结构中表结构,需要注意一些常用的关键字字段。

    吉日嘎拉,通用权限管理系统组件

    2:下图是每个字段的注释,这些注释可以在设置表字段权限时会派上大用处,不用反复输入基础数据了。

    吉日嘎拉,通用权限管理系统组件

    3:我们用代码生成器,进行相关的代码,基础配置数据的生成工作。

    吉日嘎拉,通用权限管理系统组件

    3:可以用代码生成器工具直接生成基础数据权限设置的功能,可以节省人工设置的烦恼。

    吉日嘎拉,通用权限管理系统组件

    4:运行相关自动生成脚本的效果如下:

    吉日嘎拉,通用权限管理系统组件

    5:我们用超级管理员,登录系统进行相关的配置

    吉日嘎拉,通用权限管理系统组件

    6:我们设置用户的表字段权限

    吉日嘎拉,通用权限管理系统组件

    7:超级管理员可以设置 “公开”列的配置, 然后可以给用户配置相关的数据列权限了。

    吉日嘎拉,通用权限管理系统组件
    8:我们可以在获取数据的底层函数里,直接过滤有访问权限的字段,把没有访问权限的字段,直接在底层就进行移除掉,这样系统的安全性会非常高了,可以满足安全要求非常高的信息系统的要求。

    吉日嘎拉,通用权限管理系统组件

    文章头部的几个与字段权限有关的函数主要是处理界面效果用的,上图主要是在功能函数的底层直接就把没权限访问的字段排除掉了。

    字段权限:

       a: 页面上的字段权限实现。

       b: 直接在底层就实现字段权限,把数据在底层进行进行筛选处理。

    希望以上实现的思路,可以起一些参考意义。

     

    将权限管理、工作流管理做到我能力的极致,一个人只能做好那么很少的几件事情。

    Add your comment

    5 条回复

    1. #1楼 xuefly      2012-02-06 22:41
      弄死方舟子,弄死周立波,一个人只能做好那么很少的几件事情。
       回复 引用 查看   
    2. #2楼 卡啊可下[未注册用户]2012-02-07 08:30
      @xuefly
      这人 傻B 疯了?
       回复 引用   
    3. #3楼 wy24420      2012-02-07 08:43
      有空学习,感谢楼主
       回复 引用 查看   
    4. #4楼 游客111111111111111[未注册用户]2012-02-07 10:14
      想问楼主一个问题:如果编辑方式是在一个窗体内进行新增编辑,而不是在网格内直接新增编辑,这样怎么去动态控制(隐藏或显示)那些控件
       回复 引用   
    5. #5楼 有一点难      2012-02-07 11:18
      非常不错。继续学习研究中。
       回复 引用 查看   
    展开全文
  • LC7462M--单片遥控发射器集成电路 LC7462M是日本三洋公司生产的单片遥控发射器集成电路,广泛应用于各种遥控系统中,如影碟机、空调器、电视机、音响等电子产品的遥控系统。 功能特点 LC7462M集成电路内含键位...
  • 美国公司 Control Chief 公司为机车和物料输送应用领域提供工业、无线控制解决方案已经有近 40 年的历史了。在钢铁、煤矿和粮食等行业领域,Control Chief 系统可以在不同环境中搬运大量物料,包括铁路货运编组和...
  • 该软件不是某公司出品,也不是某软件站提供下载的,就算你找尽全中国所有软件下载站点都不一定找的到这个软件。因为这是某某IT高人自己制作出来的,经过反复测试通过认证,无病毒。再经过本人的长期使用,确实很有...
  • 最近搭建了公司的后台管理系统, 而且系统还比较庞大, 要实现以下几点: 菜单权限, 根据不同权限显示不同的菜单 操作权限, 比如有些账号没有新增权限, 有些没有修改或者删除权限 数据权限, 比如统计概况, ...
  • 在大部份系统中,权限控制主要定义为模块进入权限的控制和数据访问权限的控制(如:某某人能够进入某个控制,仓库不充许查看有关金额的字段等等)。 但在某些系统中,权限控制又必须定义到数据行访问权限的控制,此...
  •  VISA是由组成VXI p1ug&p1ay系统联盟的35家最大的仪器仪表公司统一采用的标准。采用了VISA标准,说可以不考虚时间及仪器I/O选择项,驱动软件可以相互相容使用。 VISA仪器仪器控制节点位于函数先板的“仪器I/O→...
  • 在大部份系统中,权限控制主要定义为模块进入权限的控制和数据访问权限的控制(如:某某人可以进入某个控制,仓库不充许查看有关部门的字段等等)。 但在某些系统中,权限控制又必须定义到数据行访问权限的控制,此...
  • 系统集成A公司中标了一个地铁综合监控系统项目,该项目是地铁运营公司公开招标的地铁S号线建设项目中的一个信息系统子项目,涉及信号系统、电气控制系统、广播系统、视频监控系统、通信网络系统的信息互通和集中...
  • 本文监控系统由两个PC主站(其中一个是备用站)和三个子站组成,每个子站由一台Siemens57- 300PLC构成,独立控制柴油发电机组:主站和从站之间通过Profibus现场总线进行通信,利用Siemens公司的编程软件Step7设计了PLC...
  • 自动驾驶系统 bfs

    2019-04-05 10:00:00
    一家科技公司有一块试验地用于测试自动驾驶系统。试验地由n×m个格子组成,从上到下依次编号为第1到n行,从左到右依次编号为第1到m。试验车位于其中的某个格子上,每次自动驾驶系统可以控制汽车往上下左右移动一格...
  • 可以广泛用于一次性出来的改动很少的成绩查询,录取查询,证书查询系统(每个学校,教育机构,事业单位考试等都可以用到),工资查询系统(每个企业,学校,所有单位都可能用到),水电费查询系统等(小区,物业公司,大学...
  • 可以广泛用于一次性出来的改动很少的成绩查询,录取查询,证书查询系统(每个学校,教育机构,事业单位考试等都可以用到),工资查询系统(每个企业,学校,所有单位都可能用到),水电费查询系统等(小区,物业公司,大学...
  • 可以广泛用于一次性出来的改动很少的成绩查询,录取查询,证书查询系统(每个学校,教育机构,事业单位考试等都可以用到),工资查询系统(每个企业,学校,所有单位都可能用到),水电费查询系统等(小区,物业公司,大学...
  • ●保修卡管理:为每一发出产品(带机身码)生成保修卡,并记录相关的安装公司、人员及日期等,从而为每一销售的产品建档。 ●维修管理:记录客户需维修产品的进出,如产生费用,则增加其应收款; ●销售报表: 1....
  •  TFT-LCD模块的时序要求 本显示模块选用的LQ080V3DG01是Sharp公司的TFT-LCD器件,该器件的分辨率为640×480,控制时序图如图1所示,时间参数如表1所[2]。 硬件电路设计 在该显示系统的硬件电路中,S3C2410与...
  • 某信息系统集成公司最近承接了一项工程,其中包括了 8个基本活动。这些活动的名称、完成每个活动所需的时间以及与其他活动之间的关系如下表所示: 【问题 1】 为了便于对该工程的进度进行分析,请画出进度计划箭线.
  • 面对企业日益急竞争的今天,您的公司是否在为一大堆正在使用的文件、合同、或技术图纸的整理在发愁 或者说公司进行ISO质量体系人认证,作为公司的您是不是还在用EXCEL对您的文件和资料进行登记管理呢, 您...
  • 3、首页设计了高达9个后台可广告位,更灵活的应用模式让您在使用本套服装购物系统中得心应手,让设计更酷,让功能更人性。 4、具体商品展示页面中,产品展示配备大图轮换、小图缩略的效果,更能体现出服装展示的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 404
精华内容 161
关键字:

列控系统公司